diff --git a/src/public/peer.php b/src/public/peer.php
new file mode 100644
index 0000000..a4ab81e
--- /dev/null
+++ b/src/public/peer.php
@@ -0,0 +1,353 @@
+ 1 ? (int) $_GET['page'] : 1;
+$requestCalendar = !empty($_GET['calendar']) && in_array($_GET['calendar'], ['traffic']) ? $_GET['calendar'] : 'traffic';
+
+// App controller begin
+$calendar = new Yggverse\Graph\Calendar\Month($requestTime);
+
+foreach ($calendar->getNodes() as $day => $node) {
+
+ switch ($requestCalendar) {
+
+ case 'traffic':
+
+ $timeFrom = strtotime(sprintf('%s-%s-%s 00:00', date('Y', $requestTime), date('n', $requestTime), $day));
+ $timeTo = strtotime('+1 day', strtotime(sprintf('%s-%s-%s 00:00', date('Y', $requestTime), date('n', $requestTime), $day)));
+
+ $dbPeerSessionSentSumByTimeUpdated = $memory->getByMethodCallback(
+ $db, 'findPeerSessionSentSumByTimeUpdated', [$timeFrom, $timeTo, $requestPeerId]
+ );
+
+ $dbPeerSessionReceivedSumByTimeUpdated = $memory->getByMethodCallback(
+ $db, 'findPeerSessionReceivedSumByTimeUpdated', [$timeFrom, $timeTo, $requestPeerId]
+ );
+
+ // Add daily stats
+ $calendar->addNode($day, $dbPeerSessionSentSumByTimeUpdated, sprintf(_('↑ %s'), number_format($dbPeerSessionSentSumByTimeUpdated / 1000000, 3)), 'red', 0);
+ $calendar->addNode($day, $dbPeerSessionReceivedSumByTimeUpdated, sprintf(_('↓ %s'), number_format($dbPeerSessionReceivedSumByTimeUpdated / 1000000, 3)), 'green', 0);
+
+ // Add hourly stats
+ for ($hour = 0; $hour < 24; $hour++) {
+
+ $timeFrom = strtotime(sprintf('%s-%s-%s %s:00', date('Y', $requestTime), date('n', $requestTime), $day, $hour));
+ $timeTo = strtotime(sprintf('%s-%s-%s %s:00', date('Y', $requestTime), date('n', $requestTime), $day, $hour + 1));
+
+ $dbPeerSessionSentSumByTimeUpdated = $memory->getByMethodCallback(
+ $db, 'findPeerSessionSentSumByTimeUpdated', [$timeFrom, $timeTo, $requestPeerId]
+ );
+
+ $dbPeerSessionReceivedSumByTimeUpdated = $memory->getByMethodCallback(
+ $db, 'findPeerSessionReceivedSumByTimeUpdated', [$timeFrom, $timeTo, $requestPeerId]
+ );
+
+ $calendar->addNode($day, $dbPeerSessionSentSumByTimeUpdated, sprintf(_('%s:00-%s:00 ↑ %s'), $hour, $hour + 1, number_format($dbPeerSessionSentSumByTimeUpdated / 1000000, 3)), 'red', 1);
+ $calendar->addNode($day, $dbPeerSessionReceivedSumByTimeUpdated, sprintf(_('%s:00-%s:00 ↓ %s'), $hour, $hour + 1, number_format($dbPeerSessionReceivedSumByTimeUpdated / 1000000, 3)), 'green', 1);
+ }
+
+ break;
+ }
+}
+
+$peerRemoteConnections = $memory->getByMethodCallback(
+ $db,
+ 'findPeerPeerConnections',
+ [
+ $requestPeerId,
+ ($requestPage - 1) * WEBSITE_PEER_REMOTE_PAGINATION_LIMIT,
+ $requestPage + WEBSITE_PEER_REMOTE_PAGINATION_LIMIT,
+ $requestSort,
+ $requestOrder,
+ ]
+);
+
+$peerInfo = $memory->getByMethodCallback($db, 'getPeerInfo', [$requestPeerId]);
+
+?>
+
+
+
+
+
+
+
+
+ address, WEBSITE_NAME) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ $peerRemoteConnection) { ?>
+
+ timeAdded) ?> |
+ remote ?> |
+ connectionPort ?> |
+ route ?> |
+
+
+ •
+
+ |
+
+
+
+ = WEBSITE_PEER_REMOTE_PAGINATION_LIMIT) { ?>
+
+
+
+ 1) { ?>
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+ address ?> |
+
+
+ |
+ key ?> |
+
+
+ |
+ timeAdded) ?> |
+
+
+ |
+ timeOnline) ?> |
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+ uptimeAvg / 60 / 60, 2) ?> |
+
+
+ |
+ remoteTotal ?> |
+
+
+ |
+ sessionTotal ?> |
+
+
+ |
+ coordinateTotal ?> |
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+ sentSum / 1000000, 3) ?> |
+
+
+ |
+ receivedSum / 1000000, 3) ?> |
+
+
+ |
+ sentSum + $peerInfo->receivedSum) / 1000000, 3) ?> |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getNodes() as $day => $node) { ?>
+
+
+
+
+
+ $layers) { ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file