Compare commits
24 Commits
57e9bf12ca
...
hladinator
| Author | SHA1 | Date | |
|---|---|---|---|
| 5894c51256 | |||
| a1a1685ae3 | |||
| 62d69fbb1e | |||
| c8fe97078d | |||
| c4cad149ea | |||
| 4939d1c5dc | |||
| 8fe39b7ab0 | |||
| cdb653d660 | |||
| 48b44cd642 | |||
| 7a7abdd3e5 | |||
| f8a7be7fa3 | |||
| 62c861e610 | |||
| ec540e056d | |||
| 231961da19 | |||
| a67a2247c3 | |||
| cf05e844d8 | |||
| 6395df1992 | |||
| 66021e001e | |||
| db1aadcc8d | |||
| dbb22e7972 | |||
| 6d77c20c84 | |||
| a3b3d40769 | |||
| 27551f9183 | |||
| b660f0f6c3 |
@@ -22,3 +22,6 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# Documentation / Ideas
|
||||||
|
docs/
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ WORKDIR /var/www/html
|
|||||||
# Enable necessary Apache modules
|
# Enable necessary Apache modules
|
||||||
RUN a2enmod rewrite headers
|
RUN a2enmod rewrite headers
|
||||||
|
|
||||||
COPY vhost.conf /etc/apache2/sites-available/000-default.conf
|
COPY Docker/vhost.conf /etc/apache2/sites-available/000-default.conf
|
||||||
|
|
||||||
# Copy the built application from the build stage
|
# Copy the built application from the build stage
|
||||||
COPY --from=build /app/dist /app/dist
|
COPY --from=build /app/dist /app/dist
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: timescale/timescaledb:latest-pg16
|
||||||
|
container_name: hladinator-db
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: hladinator
|
||||||
|
POSTGRES_USER: hladinator_user
|
||||||
|
POSTGRES_PASSWORD: hladinator_db_password_change_me
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Docker/Dockerfile
|
||||||
|
container_name: hladinator-web
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
driver: local
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# File: .docker/apache/vhost.conf
|
# File: Docker/vhost.conf
|
||||||
LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
|
LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
|
||||||
|
|
||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
@@ -1,72 +1,102 @@
|
|||||||
# 🌊 HLADINATOR
|
# 🌊 HLADINATOR
|
||||||
|
|
||||||
HLADINATOR je interaktivní a vizuálně poutavá webová aplikace pro sledování aktuálního stavu a historie českých přehrad. Aplikace poskytuje přesná data o výšce hladiny, odtoku, přítoku, aktuálním objemu a navíc sbírá historii počasí (teploty a srážek) přímo od zdroje.
|
HLADINATOR is an interactive and visually engaging web application for monitoring the current status and history of Czech reservoirs. The application provides precise data on water level, outflow, inflow, current volume, and additionally collects weather history (temperature and precipitation) directly from the source.
|
||||||
|
|
||||||
Zdroj dat: **Povodí Vltavy (pvl.cz)** a další povodí v ČR.
|
Data source: **Povodí Vltavy (pvl.cz)** and other river basin administrators in the Czech Republic.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Jak spustit aplikaci lokálně
|
## 🚀 How to Run the Application Locally
|
||||||
|
|
||||||
Aplikace je postavena na moderním stacku (React, Vite, TypeScript, Recharts, Leaflet). Pro její spuštění nepotřebuješ žádný složitý backend, data se čtou z předgenerovaných JSON souborů.
|
The application is built on a modern stack (React, Vite, TypeScript, Recharts, Leaflet). You don't need any complex backend to run it locally; the data is read directly from pre-generated static JSON files.
|
||||||
|
|
||||||
1. Nainstaluj závislosti (pokud jsi to ještě neudělal):
|
1. Install dependencies (if you haven't already):
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
2. Spusť lokální vývojový server:
|
2. Start the local development server:
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
3. Otevři prohlížeč na adrese `http://localhost:5173`.
|
3. Open your browser at `http://localhost:5173`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Jak aktualizovat data (Scraping)
|
## 🔄 How to Update Data (Scraping)
|
||||||
|
|
||||||
Povodí Vltavy neposkytuje standardní API pro historii srážek a teplot, ani nepodporuje přímé dotazy z klientského prohlížeče (kvůli CORS a bezpečnosti). Proto využíváme vlastní **scraper**.
|
Povodí Vltavy does not provide a standard API for weather history, nor does it support direct requests from client browsers (due to CORS and security restrictions). Therefore, we use our own custom **scraper**.
|
||||||
|
|
||||||
Pro ruční stažení těch nejnovějších dat z webu povodí spusť v terminálu:
|
To manually fetch the latest data from the river basin websites, run in your terminal:
|
||||||
```bash
|
```bash
|
||||||
npm run data:update
|
npm run data:update
|
||||||
```
|
```
|
||||||
|
|
||||||
Tento příkaz provede dvě věci:
|
This command performs two actions:
|
||||||
1. `npm run scrape`: Otevře stránky povodí pro všech 12 přehrad, přečte tabulky s historickými měřeními a najde "Aktuální hodnoty", odkud vytáhne exaktní **přítok, objem, srážky a teplotu**. Tato data inteligentně sloučí s tvojí lokální databází (`public/data/*.json`). Pokud Povodí aktuálně počasí neposkytuje, skript zrecykluje tvou dřívější uloženou hodnotu, aby se graf "nerozbil".
|
1. `npm run scrape`: Scrapes the website for all **53 reservoirs and river stations**, parses historical measurement tables, extracts precise **inflow, outflow, volume, precipitation, and temperature**. It then merges this data intelligently with your local database (`public/data/*.json`) and automatically backfills missing values from previous steps to avoid zero-drop anomalies in the charts.
|
||||||
2. `npm run build-index`: Zaktualizuje hlavní indexový soubor `lakes_index.json`, který aplikace využívá pro vykreslení rychlých náhledů (např. v levém menu nebo na mapě).
|
2. `npm run build-index`: Updates the main index file `lakes_index.json`, which the app uses to render fast previews (e.g., in the side menu or on the map).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⏰ Automatické stahování dat (Cron / Spouštěč)
|
## ⏰ Automated Data Updates (Cron / Scheduler)
|
||||||
|
|
||||||
Aby se ti automaticky budovala bohatá historie počasí a srážek i ve chvíli, kdy spíš, doporučuji nastavit automatické spouštění skriptu `npm run data:update`.
|
To automatically accumulate weather and precipitation history even when your machine is off or you are sleeping, we recommend automating the execution of the `npm run data:update` script.
|
||||||
|
|
||||||
Zde jsou nejběžnější možnosti, jak si to můžeš nastavit ty sám:
|
Here are the most common deployment methods:
|
||||||
|
|
||||||
### Možnost A: Přes Crontab na Macu / Linuxu (Lokálně)
|
### Option A: Using Crontab on macOS / Linux (Local)
|
||||||
Pokud ti běží počítač (nebo domácí server/Raspberry Pi) nepřetržitě, můžeš využít systémový `cron`.
|
If you have a computer or home server (like a Raspberry Pi) running continuously:
|
||||||
1. Otevři terminál a napiš: `crontab -e`
|
1. Open the terminal and type: `crontab -e`
|
||||||
2. Na konec souboru vlož následující řádek (uprav cestu ke svému projektu a Node.js):
|
2. Add the following line at the end of the file (adjust the paths to your project and Node.js installation):
|
||||||
```bash
|
```bash
|
||||||
# Spustit scraping každých 15 minut
|
# Run scraping every 15 minutes
|
||||||
*/15 * * * * cd /Users/davis/WebstormProjects/davisfe.cz && /usr/local/bin/npm run data:update >> scraper.log 2>&1
|
*/15 * * * * cd /Users/davis/WebstormProjects/davisfe.cz && /usr/local/bin/npm run data:update >> scraper.log 2>&1
|
||||||
```
|
```
|
||||||
3. Ulož a zavři editor. Od této chvíle se systém postará o automatický sběr dat!
|
3. Save and close the editor. The system scheduler will take care of the rest.
|
||||||
|
|
||||||
### Možnost B: Pomocí GitHub Actions (Pro Produkci)
|
### Option B: Using GitHub Actions (For Production Hosting)
|
||||||
Až projekt nahraješ na GitHub, můžeš si vytvořit workflow soubor (např. `.github/workflows/scrape.yml`), který bude skript spouštět na serverech GitHubu zdarma každou hodinu, a výsledné `.json` soubory automaticky commitne a publikuje na web.
|
Once you push the project to GitHub, you can create a workflow file (e.g., `.github/workflows/scrape.yml`) to run the scraping script every hour on GitHub runners for free, and automatically commit and publish the updated `.json` data files back to the repository.
|
||||||
|
|
||||||
### Možnost C: Jednoduchý integrovaný spouštěč (Nejlehčí)
|
### Option C: Built-in Simple Scheduler (Recommended for Development)
|
||||||
Pokud nechceš řešit složitý systémový crontab, napsal jsem pro tebe přímo do Node.js malý spouštěč. Stačí si otevřít další okno terminálu a napsat:
|
If you do not want to set up system cron, the project has a built-in scheduler. Open another terminal tab/window and run:
|
||||||
```bash
|
```bash
|
||||||
npm run data:watch 10
|
npm run data:watch
|
||||||
```
|
```
|
||||||
Tento příkaz ihned provede první stažení a následně bude aplikaci automaticky aktualizovat **každých 10 minut** (číslo na konci si můžeš libovolně přepsat podle toho, jak často chceš stahovat). Skript poběží, dokud okno terminálu nezavřeš.
|
This command triggers an immediate update and then automatically schedules updates at 7 minutes past every 10-minute step (e.g., 18:07, 18:17, 18:27...). This delay ensures that the river basin web page has updated its data, preventing duplicate/empty requests.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Struktura klíčových datových složek
|
## 🐳 Running in Docker (Production & Own Server)
|
||||||
|
|
||||||
* `/scripts/lakesConfig.ts` - Tady najdeš definici všech 12 sledovaných přehrad (včetně jejich ID pro Povodí Vltavy, GPS souřadnic, maximálních objemů a stavebních kót). Sem můžeš přidávat nové přehrady.
|
If you want to deploy the application on your own server and run a PostgreSQL (TimescaleDB) database alongside it for future data collection, a Docker Compose configuration is prepared inside the `Docker` directory.
|
||||||
* `/public/data/` - Zde se ukládají vygenerovaná JSON data. V produkci musí být tyto soubory přístupné jako statické assety.
|
|
||||||
* `/src/components/` - Obsahuje samotné vizuální karty, Leaflet mapu a detailní `LakeDetail.tsx` (kde se vykresluje hydrologický a meteorologický graf přes Recharts).
|
### Requirements:
|
||||||
|
- Installed **Docker** and **Docker Compose**.
|
||||||
|
|
||||||
|
### Deployment:
|
||||||
|
1. Go to the `Docker` directory and build/run the containers in the background:
|
||||||
|
```bash
|
||||||
|
cd Docker
|
||||||
|
docker-compose up -d --build
|
||||||
|
```
|
||||||
|
2. Docker Compose will launch two containers:
|
||||||
|
- **`hladinator-db`**: PostgreSQL (TimescaleDB) database running on port `5432` with a `pgdata` volume for data persistence.
|
||||||
|
- **`hladinator-web`**: Apache web server serving the built React static application on port `80`.
|
||||||
|
|
||||||
|
3. The web application is then accessible on port `80` of your server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Fixing Anomalies in History (Zero Drops / Teeth in Graphs)
|
||||||
|
|
||||||
|
If the scraper hasn't run for a while (e.g., when your computer was turned off) and data was filled in subsequently, anomalies or drops to zero (teeth) might appear in the inflow and volume graphs. To clean up the entire history and interpolate these points from the last known state, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run data:fix
|
||||||
|
```
|
||||||
|
This script scans all data JSON files, detects anomalies/zeros, and repairs them.
|
||||||
|
|
||||||
|
## 📁 Key File and Folder Structure
|
||||||
|
|
||||||
|
* `/scripts/lakesConfig.ts` - Contains configuration definitions for all **53 monitored reservoirs and rivers** (including their river basin ID, GPS coordinates, maximum capacity limits, and elevation heights). You can add new stations here.
|
||||||
|
* `/public/data/` - Static storage location for generated JSON files. In production, these must be exposed as static assets.
|
||||||
|
* `/src/components/` - Holds user interface components, the Leaflet map, and `LakeDetail.tsx` (renders historical hydrology and weather charts via Recharts with automatic anomaly filtering).
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import * as cheerio from 'cheerio';
|
||||||
|
import fs from 'fs';
|
||||||
|
import https from 'https';
|
||||||
|
|
||||||
|
async function compare() {
|
||||||
|
const URL = 'https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?oid=1&id=VLL1';
|
||||||
|
const agent = new https.Agent({ rejectUnauthorized: false });
|
||||||
|
const response = await axios.get(URL, { httpsAgent: agent });
|
||||||
|
const $ = cheerio.load(response.data);
|
||||||
|
|
||||||
|
let tblFound = null;
|
||||||
|
$('table').each((i, tbl) => {
|
||||||
|
if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) {
|
||||||
|
tblFound = $(tbl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const pvlRows = [];
|
||||||
|
if (tblFound) {
|
||||||
|
tblFound.find('tr').each((i, row) => {
|
||||||
|
if (i === 0) return;
|
||||||
|
const cols = $(row).find('td');
|
||||||
|
if (cols.length >= 3) {
|
||||||
|
const rawDate = $(cols[0]).text().trim();
|
||||||
|
const levelStr = $(cols[1]).text().trim().replace(',', '.');
|
||||||
|
let flowStr = $(cols[2]).text().trim().replace(',', '.');
|
||||||
|
if (flowStr === '' && cols.length >= 4) {
|
||||||
|
flowStr = $(cols[3]).text().trim().replace(',', '.');
|
||||||
|
}
|
||||||
|
pvlRows.push({
|
||||||
|
date: rawDate,
|
||||||
|
level: parseFloat(levelStr),
|
||||||
|
flow: parseFloat(flowStr)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const localData = JSON.parse(fs.readFileSync('public/data/VLL1.json', 'utf-8'));
|
||||||
|
// Sort local data descending (newest first) to match PVL which is newest first
|
||||||
|
const sortedLocal = localData.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
||||||
|
|
||||||
|
console.log('--- POROVNÁNÍ DAT: LIPNO 1 ---');
|
||||||
|
console.log(String('PVL.CZ').padEnd(40) + ' | ' + 'NAŠE LOKÁLNÍ DATABÁZE');
|
||||||
|
console.log('-'.repeat(85));
|
||||||
|
|
||||||
|
for (let i = 0; i < Math.min(10, pvlRows.length); i++) {
|
||||||
|
const p = pvlRows[i];
|
||||||
|
const l = sortedLocal[i];
|
||||||
|
|
||||||
|
// Format our local UTC timestamp back to something readable
|
||||||
|
const d = new Date(l.timestamp);
|
||||||
|
const localDateStr = `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth()+1).toString().padStart(2, '0')}.${d.getFullYear()} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
|
||||||
|
|
||||||
|
const pvlStr = `[${p.date}] H: ${p.level} m, O: ${p.flow} m3/s`.padEnd(40);
|
||||||
|
const locStr = `[${localDateStr}] H: ${l.level} m, O: ${l.flow} m3/s, P: ${l.inflow} m3/s`;
|
||||||
|
|
||||||
|
console.log(`${pvlStr} | ${locStr}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compare().catch(console.error);
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
body, html {
|
|
||||||
margin:0; padding: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family: Helvetica Neue, Helvetica, Arial;
|
|
||||||
font-size: 14px;
|
|
||||||
color:#333;
|
|
||||||
}
|
|
||||||
.small { font-size: 12px; }
|
|
||||||
*, *:after, *:before {
|
|
||||||
-webkit-box-sizing:border-box;
|
|
||||||
-moz-box-sizing:border-box;
|
|
||||||
box-sizing:border-box;
|
|
||||||
}
|
|
||||||
h1 { font-size: 20px; margin: 0;}
|
|
||||||
h2 { font-size: 14px; }
|
|
||||||
pre {
|
|
||||||
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-moz-tab-size: 2;
|
|
||||||
-o-tab-size: 2;
|
|
||||||
tab-size: 2;
|
|
||||||
}
|
|
||||||
a { color:#0074D9; text-decoration:none; }
|
|
||||||
a:hover { text-decoration:underline; }
|
|
||||||
.strong { font-weight: bold; }
|
|
||||||
.space-top1 { padding: 10px 0 0 0; }
|
|
||||||
.pad2y { padding: 20px 0; }
|
|
||||||
.pad1y { padding: 10px 0; }
|
|
||||||
.pad2x { padding: 0 20px; }
|
|
||||||
.pad2 { padding: 20px; }
|
|
||||||
.pad1 { padding: 10px; }
|
|
||||||
.space-left2 { padding-left:55px; }
|
|
||||||
.space-right2 { padding-right:20px; }
|
|
||||||
.center { text-align:center; }
|
|
||||||
.clearfix { display:block; }
|
|
||||||
.clearfix:after {
|
|
||||||
content:'';
|
|
||||||
display:block;
|
|
||||||
height:0;
|
|
||||||
clear:both;
|
|
||||||
visibility:hidden;
|
|
||||||
}
|
|
||||||
.fl { float: left; }
|
|
||||||
@media only screen and (max-width:640px) {
|
|
||||||
.col3 { width:100%; max-width:100%; }
|
|
||||||
.hide-mobile { display:none!important; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.quiet {
|
|
||||||
color: #7f7f7f;
|
|
||||||
color: rgba(0,0,0,0.5);
|
|
||||||
}
|
|
||||||
.quiet a { opacity: 0.7; }
|
|
||||||
|
|
||||||
.fraction {
|
|
||||||
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #555;
|
|
||||||
background: #E8E8E8;
|
|
||||||
padding: 4px 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.path a:link, div.path a:visited { color: #333; }
|
|
||||||
table.coverage {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 10px 0 0 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.coverage td {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
table.coverage td.line-count {
|
|
||||||
text-align: right;
|
|
||||||
padding: 0 5px 0 20px;
|
|
||||||
}
|
|
||||||
table.coverage td.line-coverage {
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 10px;
|
|
||||||
min-width:20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.coverage td span.cline-any {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 5px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.missing-if-branch {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
position: relative;
|
|
||||||
padding: 0 4px;
|
|
||||||
background: #333;
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skip-if-branch {
|
|
||||||
display: none;
|
|
||||||
margin-right: 10px;
|
|
||||||
position: relative;
|
|
||||||
padding: 0 4px;
|
|
||||||
background: #ccc;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.missing-if-branch .typ, .skip-if-branch .typ {
|
|
||||||
color: inherit !important;
|
|
||||||
}
|
|
||||||
.coverage-summary {
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
|
||||||
.keyline-all { border: 1px solid #ddd; }
|
|
||||||
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
|
||||||
.coverage-summary tbody { border: 1px solid #bbb; }
|
|
||||||
.coverage-summary td { border-right: 1px solid #bbb; }
|
|
||||||
.coverage-summary td:last-child { border-right: none; }
|
|
||||||
.coverage-summary th {
|
|
||||||
text-align: left;
|
|
||||||
font-weight: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.coverage-summary th.file { border-right: none !important; }
|
|
||||||
.coverage-summary th.pct { }
|
|
||||||
.coverage-summary th.pic,
|
|
||||||
.coverage-summary th.abs,
|
|
||||||
.coverage-summary td.pct,
|
|
||||||
.coverage-summary td.abs { text-align: right; }
|
|
||||||
.coverage-summary td.file { white-space: nowrap; }
|
|
||||||
.coverage-summary td.pic { min-width: 120px !important; }
|
|
||||||
.coverage-summary tfoot td { }
|
|
||||||
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
height: 10px;
|
|
||||||
width: 7px;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 0.5em;
|
|
||||||
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
|
||||||
}
|
|
||||||
.coverage-summary .sorted .sorter {
|
|
||||||
background-position: 0 -20px;
|
|
||||||
}
|
|
||||||
.coverage-summary .sorted-desc .sorter {
|
|
||||||
background-position: 0 -10px;
|
|
||||||
}
|
|
||||||
.status-line { height: 10px; }
|
|
||||||
/* yellow */
|
|
||||||
.cbranch-no { background: yellow !important; color: #111; }
|
|
||||||
/* dark red */
|
|
||||||
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
|
||||||
.low .chart { border:1px solid #C21F39 }
|
|
||||||
.highlighted,
|
|
||||||
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
|
||||||
background: #C21F39 !important;
|
|
||||||
}
|
|
||||||
/* medium red */
|
|
||||||
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
|
||||||
/* light red */
|
|
||||||
.low, .cline-no { background:#FCE1E5 }
|
|
||||||
/* light green */
|
|
||||||
.high, .cline-yes { background:rgb(230,245,208) }
|
|
||||||
/* medium green */
|
|
||||||
.cstat-yes { background:rgb(161,215,106) }
|
|
||||||
/* dark green */
|
|
||||||
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
|
||||||
.high .chart { border:1px solid rgb(77,146,33) }
|
|
||||||
/* dark yellow (gold) */
|
|
||||||
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
|
||||||
.medium .chart { border:1px solid #f9cd0b; }
|
|
||||||
/* light yellow */
|
|
||||||
.medium { background: #fff4c2; }
|
|
||||||
|
|
||||||
.cstat-skip { background: #ddd; color: #111; }
|
|
||||||
.fstat-skip { background: #ddd; color: #111 !important; }
|
|
||||||
.cbranch-skip { background: #ddd !important; color: #111; }
|
|
||||||
|
|
||||||
span.cline-neutral { background: #eaeaea; }
|
|
||||||
|
|
||||||
.coverage-summary td.empty {
|
|
||||||
opacity: .5;
|
|
||||||
padding-top: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
line-height: 1;
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cover-fill, .cover-empty {
|
|
||||||
display:inline-block;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
.chart {
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
.cover-empty {
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
.cover-full {
|
|
||||||
border-right: none !important;
|
|
||||||
}
|
|
||||||
pre.prettyprint {
|
|
||||||
border: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
}
|
|
||||||
.com { color: #999 !important; }
|
|
||||||
.ignore-none { color: #999; font-weight: normal; }
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
min-height: 100%;
|
|
||||||
height: auto !important;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0 auto -48px;
|
|
||||||
}
|
|
||||||
.footer, .push {
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
var jumpToCode = (function init() {
|
|
||||||
// Classes of code we would like to highlight in the file view
|
|
||||||
var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
|
|
||||||
|
|
||||||
// Elements to highlight in the file listing view
|
|
||||||
var fileListingElements = ['td.pct.low'];
|
|
||||||
|
|
||||||
// We don't want to select elements that are direct descendants of another match
|
|
||||||
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
|
|
||||||
|
|
||||||
// Selector that finds elements on the page to which we can jump
|
|
||||||
var selector =
|
|
||||||
fileListingElements.join(', ') +
|
|
||||||
', ' +
|
|
||||||
notSelector +
|
|
||||||
missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
|
|
||||||
|
|
||||||
// The NodeList of matching elements
|
|
||||||
var missingCoverageElements = document.querySelectorAll(selector);
|
|
||||||
|
|
||||||
var currentIndex;
|
|
||||||
|
|
||||||
function toggleClass(index) {
|
|
||||||
missingCoverageElements
|
|
||||||
.item(currentIndex)
|
|
||||||
.classList.remove('highlighted');
|
|
||||||
missingCoverageElements.item(index).classList.add('highlighted');
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeCurrent(index) {
|
|
||||||
toggleClass(index);
|
|
||||||
currentIndex = index;
|
|
||||||
missingCoverageElements.item(index).scrollIntoView({
|
|
||||||
behavior: 'smooth',
|
|
||||||
block: 'center',
|
|
||||||
inline: 'center'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function goToPrevious() {
|
|
||||||
var nextIndex = 0;
|
|
||||||
if (typeof currentIndex !== 'number' || currentIndex === 0) {
|
|
||||||
nextIndex = missingCoverageElements.length - 1;
|
|
||||||
} else if (missingCoverageElements.length > 1) {
|
|
||||||
nextIndex = currentIndex - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
makeCurrent(nextIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
function goToNext() {
|
|
||||||
var nextIndex = 0;
|
|
||||||
|
|
||||||
if (
|
|
||||||
typeof currentIndex === 'number' &&
|
|
||||||
currentIndex < missingCoverageElements.length - 1
|
|
||||||
) {
|
|
||||||
nextIndex = currentIndex + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
makeCurrent(nextIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return function jump(event) {
|
|
||||||
if (
|
|
||||||
document.getElementById('fileSearch') === document.activeElement &&
|
|
||||||
document.activeElement != null
|
|
||||||
) {
|
|
||||||
// if we're currently focused on the search input, we don't want to navigate
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.which) {
|
|
||||||
case 78: // n
|
|
||||||
case 74: // j
|
|
||||||
goToNext();
|
|
||||||
break;
|
|
||||||
case 66: // b
|
|
||||||
case 75: // k
|
|
||||||
case 80: // p
|
|
||||||
goToPrevious();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
window.addEventListener('keydown', jumpToCode);
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<coverage generated="1780693430332" clover="3.2.0">
|
|
||||||
<project timestamp="1780693430332" name="All files">
|
|
||||||
<metrics statements="106" coveredstatements="32" conditionals="98" coveredconditionals="29" methods="18" coveredmethods="5" elements="222" coveredelements="66" complexity="0" loc="106" ncloc="106" packages="3" files="4" classes="4"/>
|
|
||||||
<package name="scripts">
|
|
||||||
<metrics statements="93" coveredstatements="24" conditionals="75" coveredconditionals="14" methods="12" coveredmethods="3"/>
|
|
||||||
<file name="lakesConfig.ts" path="/Users/davis/WebstormProjects/davisfe.cz/scripts/lakesConfig.ts">
|
|
||||||
<metrics statements="1" coveredstatements="1" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
|
|
||||||
<line num="12" count="1" type="stmt"/>
|
|
||||||
</file>
|
|
||||||
<file name="scrapeLakes.ts" path="/Users/davis/WebstormProjects/davisfe.cz/scripts/scrapeLakes.ts">
|
|
||||||
<metrics statements="92" coveredstatements="23" conditionals="75" coveredconditionals="14" methods="12" coveredmethods="3"/>
|
|
||||||
<line num="20" count="7" type="stmt"/>
|
|
||||||
<line num="21" count="7" type="cond" truecount="4" falsecount="0"/>
|
|
||||||
<line num="22" count="4" type="stmt"/>
|
|
||||||
<line num="23" count="4" type="stmt"/>
|
|
||||||
<line num="24" count="4" type="stmt"/>
|
|
||||||
<line num="26" count="4" type="cond" truecount="4" falsecount="0"/>
|
|
||||||
<line num="28" count="2" type="stmt"/>
|
|
||||||
<line num="29" count="2" type="stmt"/>
|
|
||||||
<line num="30" count="2" type="stmt"/>
|
|
||||||
<line num="31" count="2" type="stmt"/>
|
|
||||||
<line num="32" count="2" type="cond" truecount="1" falsecount="1"/>
|
|
||||||
<line num="33" count="2" type="cond" truecount="5" falsecount="0"/>
|
|
||||||
<line num="34" count="1" type="stmt"/>
|
|
||||||
<line num="36" count="0" type="stmt"/>
|
|
||||||
<line num="41" count="1" type="stmt"/>
|
|
||||||
<line num="42" count="1" type="stmt"/>
|
|
||||||
<line num="44" count="1" type="stmt"/>
|
|
||||||
<line num="45" count="1" type="stmt"/>
|
|
||||||
<line num="46" count="1" type="stmt"/>
|
|
||||||
<line num="53" count="0" type="stmt"/>
|
|
||||||
<line num="55" count="0" type="stmt"/>
|
|
||||||
<line num="56" count="0" type="stmt"/>
|
|
||||||
<line num="57" count="0" type="stmt"/>
|
|
||||||
<line num="58" count="0" type="stmt"/>
|
|
||||||
<line num="60" count="0" type="stmt"/>
|
|
||||||
<line num="61" count="0" type="stmt"/>
|
|
||||||
<line num="62" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="63" count="0" type="stmt"/>
|
|
||||||
<line num="64" count="0" type="stmt"/>
|
|
||||||
<line num="65" count="0" type="stmt"/>
|
|
||||||
<line num="66" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="67" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="68" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="69" count="0" type="stmt"/>
|
|
||||||
<line num="70" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="72" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="73" count="0" type="stmt"/>
|
|
||||||
<line num="74" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="80" count="0" type="stmt"/>
|
|
||||||
<line num="81" count="0" type="stmt"/>
|
|
||||||
<line num="82" count="0" type="stmt"/>
|
|
||||||
<line num="83" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="84" count="0" type="stmt"/>
|
|
||||||
<line num="88" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="89" count="0" type="stmt"/>
|
|
||||||
<line num="90" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="91" count="0" type="stmt"/>
|
|
||||||
<line num="92" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="93" count="0" type="stmt"/>
|
|
||||||
<line num="94" count="0" type="stmt"/>
|
|
||||||
<line num="95" count="0" type="stmt"/>
|
|
||||||
<line num="96" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="97" count="0" type="stmt"/>
|
|
||||||
<line num="100" count="0" type="stmt"/>
|
|
||||||
<line num="101" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="102" count="0" type="stmt"/>
|
|
||||||
<line num="114" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="116" count="0" type="stmt"/>
|
|
||||||
<line num="117" count="0" type="stmt"/>
|
|
||||||
<line num="118" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="119" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="122" count="0" type="stmt"/>
|
|
||||||
<line num="123" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="124" count="0" type="stmt"/>
|
|
||||||
<line num="125" count="0" type="stmt"/>
|
|
||||||
<line num="128" count="0" type="stmt"/>
|
|
||||||
<line num="129" count="0" type="stmt"/>
|
|
||||||
<line num="130" count="0" type="stmt"/>
|
|
||||||
<line num="132" count="0" type="stmt"/>
|
|
||||||
<line num="133" count="0" type="stmt"/>
|
|
||||||
<line num="137" count="0" type="stmt"/>
|
|
||||||
<line num="138" count="0" type="stmt"/>
|
|
||||||
<line num="139" count="0" type="stmt"/>
|
|
||||||
<line num="140" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="141" count="0" type="stmt"/>
|
|
||||||
<line num="142" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="143" count="0" type="stmt"/>
|
|
||||||
<line num="146" count="0" type="cond" truecount="0" falsecount="4"/>
|
|
||||||
<line num="147" count="0" type="stmt"/>
|
|
||||||
<line num="148" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
||||||
<line num="149" count="0" type="stmt"/>
|
|
||||||
<line num="153" count="0" type="stmt"/>
|
|
||||||
<line num="154" count="0" type="stmt"/>
|
|
||||||
<line num="156" count="0" type="stmt"/>
|
|
||||||
<line num="159" count="0" type="stmt"/>
|
|
||||||
<line num="164" count="1" type="stmt"/>
|
|
||||||
<line num="166" count="1" type="stmt"/>
|
|
||||||
<line num="168" count="1" type="stmt"/>
|
|
||||||
<line num="169" count="1" type="stmt"/>
|
|
||||||
<line num="171" count="0" type="stmt"/>
|
|
||||||
<line num="174" count="0" type="stmt"/>
|
|
||||||
<line num="177" count="1" type="stmt"/>
|
|
||||||
</file>
|
|
||||||
</package>
|
|
||||||
<package name="src">
|
|
||||||
<metrics statements="1" coveredstatements="1" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
|
|
||||||
<file name="translations.ts" path="/Users/davis/WebstormProjects/davisfe.cz/src/translations.ts">
|
|
||||||
<metrics statements="1" coveredstatements="1" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>
|
|
||||||
<line num="3" count="2" type="stmt"/>
|
|
||||||
</file>
|
|
||||||
</package>
|
|
||||||
<package name="src.components">
|
|
||||||
<metrics statements="12" coveredstatements="7" conditionals="23" coveredconditionals="15" methods="6" coveredmethods="2"/>
|
|
||||||
<file name="KpiCards.tsx" path="/Users/davis/WebstormProjects/davisfe.cz/src/components/KpiCards.tsx">
|
|
||||||
<metrics statements="12" coveredstatements="7" conditionals="23" coveredconditionals="15" methods="6" coveredmethods="2"/>
|
|
||||||
<line num="21" count="1" type="cond" truecount="1" falsecount="0"/>
|
|
||||||
<line num="22" count="3" type="stmt"/>
|
|
||||||
<line num="23" count="3" type="stmt"/>
|
|
||||||
<line num="24" count="3" type="stmt"/>
|
|
||||||
<line num="26" count="3" type="stmt"/>
|
|
||||||
<line num="27" count="3" type="cond" truecount="1" falsecount="1"/>
|
|
||||||
<line num="28" count="0" type="stmt"/>
|
|
||||||
<line num="29" count="0" type="stmt"/>
|
|
||||||
<line num="31" count="0" type="stmt"/>
|
|
||||||
<line num="35" count="3" type="stmt"/>
|
|
||||||
<line num="86" count="0" type="stmt"/>
|
|
||||||
<line num="93" count="0" type="stmt"/>
|
|
||||||
</file>
|
|
||||||
</package>
|
|
||||||
</project>
|
|
||||||
</coverage>
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 445 B |
@@ -1,146 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for All files</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="prettify.css" />
|
|
||||||
<link rel="stylesheet" href="base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1>All files</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">28.92% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>35/121</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">29.59% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>29/98</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">27.77% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>5/18</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">30.18% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>32/106</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line low'></div>
|
|
||||||
<div class="pad1">
|
|
||||||
<table class="coverage-summary">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
|
||||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
|
||||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
|
||||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
|
||||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
|
||||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
|
||||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody><tr>
|
|
||||||
<td class="file low" data-value="scripts"><a href="scripts/index.html">scripts</a></td>
|
|
||||||
<td data-value="25.23" class="pic low">
|
|
||||||
<div class="chart"><div class="cover-fill" style="width: 25%"></div><div class="cover-empty" style="width: 75%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="25.23" class="pct low">25.23%</td>
|
|
||||||
<td data-value="107" class="abs low">27/107</td>
|
|
||||||
<td data-value="18.66" class="pct low">18.66%</td>
|
|
||||||
<td data-value="75" class="abs low">14/75</td>
|
|
||||||
<td data-value="25" class="pct low">25%</td>
|
|
||||||
<td data-value="12" class="abs low">3/12</td>
|
|
||||||
<td data-value="25.8" class="pct low">25.8%</td>
|
|
||||||
<td data-value="93" class="abs low">24/93</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="file high" data-value="src"><a href="src/index.html">src</a></td>
|
|
||||||
<td data-value="100" class="pic high">
|
|
||||||
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="file medium" data-value="src/components"><a href="src/components/index.html">src/components</a></td>
|
|
||||||
<td data-value="53.84" class="pic medium">
|
|
||||||
<div class="chart"><div class="cover-fill" style="width: 53%"></div><div class="cover-empty" style="width: 47%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="53.84" class="pct medium">53.84%</td>
|
|
||||||
<td data-value="13" class="abs medium">7/13</td>
|
|
||||||
<td data-value="65.21" class="pct medium">65.21%</td>
|
|
||||||
<td data-value="23" class="abs medium">15/23</td>
|
|
||||||
<td data-value="33.33" class="pct low">33.33%</td>
|
|
||||||
<td data-value="6" class="abs low">2/6</td>
|
|
||||||
<td data-value="58.33" class="pct medium">58.33%</td>
|
|
||||||
<td data-value="12" class="abs medium">7/12</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="sorter.js"></script>
|
|
||||||
<script src="block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,131 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for scripts</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../index.html">All files</a> scripts</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">25.23% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>27/107</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">18.66% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>14/75</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">25% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>3/12</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">25.8% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>24/93</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line low'></div>
|
|
||||||
<div class="pad1">
|
|
||||||
<table class="coverage-summary">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
|
||||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
|
||||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
|
||||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
|
||||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
|
||||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
|
||||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody><tr>
|
|
||||||
<td class="file high" data-value="lakesConfig.ts"><a href="lakesConfig.ts.html">lakesConfig.ts</a></td>
|
|
||||||
<td data-value="100" class="pic high">
|
|
||||||
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="file low" data-value="scrapeLakes.ts"><a href="scrapeLakes.ts.html">scrapeLakes.ts</a></td>
|
|
||||||
<td data-value="24.52" class="pic low">
|
|
||||||
<div class="chart"><div class="cover-fill" style="width: 24%"></div><div class="cover-empty" style="width: 76%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="24.52" class="pct low">24.52%</td>
|
|
||||||
<td data-value="106" class="abs low">26/106</td>
|
|
||||||
<td data-value="18.66" class="pct low">18.66%</td>
|
|
||||||
<td data-value="75" class="abs low">14/75</td>
|
|
||||||
<td data-value="25" class="pct low">25%</td>
|
|
||||||
<td data-value="12" class="abs low">3/12</td>
|
|
||||||
<td data-value="25" class="pct low">25%</td>
|
|
||||||
<td data-value="92" class="abs low">23/92</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../sorter.js"></script>
|
|
||||||
<script src="../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for scripts/lakesConfig.ts</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../index.html">All files</a> / <a href="index.html">scripts</a> lakesConfig.ts</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line high'></div>
|
|
||||||
<pre><table class="coverage">
|
|
||||||
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
||||||
<a name='L2'></a><a href='#L2'>2</a>
|
|
||||||
<a name='L3'></a><a href='#L3'>3</a>
|
|
||||||
<a name='L4'></a><a href='#L4'>4</a>
|
|
||||||
<a name='L5'></a><a href='#L5'>5</a>
|
|
||||||
<a name='L6'></a><a href='#L6'>6</a>
|
|
||||||
<a name='L7'></a><a href='#L7'>7</a>
|
|
||||||
<a name='L8'></a><a href='#L8'>8</a>
|
|
||||||
<a name='L9'></a><a href='#L9'>9</a>
|
|
||||||
<a name='L10'></a><a href='#L10'>10</a>
|
|
||||||
<a name='L11'></a><a href='#L11'>11</a>
|
|
||||||
<a name='L12'></a><a href='#L12'>12</a>
|
|
||||||
<a name='L13'></a><a href='#L13'>13</a>
|
|
||||||
<a name='L14'></a><a href='#L14'>14</a>
|
|
||||||
<a name='L15'></a><a href='#L15'>15</a>
|
|
||||||
<a name='L16'></a><a href='#L16'>16</a>
|
|
||||||
<a name='L17'></a><a href='#L17'>17</a>
|
|
||||||
<a name='L18'></a><a href='#L18'>18</a>
|
|
||||||
<a name='L19'></a><a href='#L19'>19</a>
|
|
||||||
<a name='L20'></a><a href='#L20'>20</a>
|
|
||||||
<a name='L21'></a><a href='#L21'>21</a>
|
|
||||||
<a name='L22'></a><a href='#L22'>22</a>
|
|
||||||
<a name='L23'></a><a href='#L23'>23</a>
|
|
||||||
<a name='L24'></a><a href='#L24'>24</a>
|
|
||||||
<a name='L25'></a><a href='#L25'>25</a>
|
|
||||||
<a name='L26'></a><a href='#L26'>26</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">export interface LakeConfig {
|
|
||||||
id: string;
|
|
||||||
text: string;
|
|
||||||
priority?: boolean;
|
|
||||||
coords: [number, number];
|
|
||||||
maxVolume?: number;
|
|
||||||
minLevel?: number;
|
|
||||||
maxLevel?: number;
|
|
||||||
storageLevel?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const lakesConfig: LakeConfig[] = [
|
|
||||||
{ id: "VLL1|1", text: "VD Lipno 1 - Vltava", priority: true, coords: [48.6322, 14.2215], maxVolume: 306.0, minLevel: 715.00, maxLevel: 725.60, storageLevel: 724.9 },
|
|
||||||
{ id: "VLL2|1", text: "VD Lipno II - Vltava", coords: [48.6250, 14.3180], maxVolume: 1.5, minLevel: 510.0, maxLevel: 511.5, storageLevel: 511.5 },
|
|
||||||
{ id: "VLHN|1", text: "VD Hněvkovice - Vltava", priority: true, coords: [49.1830, 14.4440], maxVolume: 21.1, minLevel: 365.0, maxLevel: 370.5, storageLevel: 370.1 },
|
|
||||||
{ id: "VLKO|1", text: "VD Kořensko - Vltava", coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 352.0, maxLevel: 353.5, storageLevel: 352.6 },
|
|
||||||
{ id: "VLOR|2", text: "VD Orlík - Vltava", priority: true, coords: [49.6060, 14.1700], maxVolume: 716.5, minLevel: 330.00, maxLevel: 354.00, storageLevel: 349.9 },
|
|
||||||
{ id: "UHKA|2", text: "VD Kamýk - Vltava", coords: [49.6360, 14.2540], maxVolume: 12.8, minLevel: 283.0, maxLevel: 285.6, storageLevel: 285.6 },
|
|
||||||
{ id: "VLSL|2", text: "VD Slapy - Vltava", priority: true, coords: [49.8220, 14.4360], maxVolume: 269.3, minLevel: 265.50, maxLevel: 271.10, storageLevel: 270.6 },
|
|
||||||
{ id: "VLST|2", text: "VD Štěchovice - Vltava", coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 217.0, maxLevel: 219.5, storageLevel: 219.4 },
|
|
||||||
{ id: "VRSN|2", text: "VD Vrané - Vltava", coords: [49.9340, 14.3850], maxVolume: 11.1, minLevel: 198.5, maxLevel: 200.5, storageLevel: 200.5 },
|
|
||||||
{ id: "SVKR|2", text: "VD Švihov - Želivka", priority: true, coords: [49.7180, 15.1060], maxVolume: 266.6, minLevel: 343.0, maxLevel: 377.0, storageLevel: 377.0 },
|
|
||||||
{ id: "MARI|1", text: "VD Římov - Malše", priority: true, coords: [48.8470, 14.4870], maxVolume: 33.8, minLevel: 458.0, maxLevel: 471.0, storageLevel: 470.65 },
|
|
||||||
{ id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 360.0, maxLevel: 373.0, storageLevel: 354.1 }
|
|
||||||
];
|
|
||||||
</pre></td></tr></table></pre>
|
|
||||||
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../sorter.js"></script>
|
|
||||||
<script src="../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1,616 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for scripts/scrapeLakes.ts</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../index.html">All files</a> / <a href="index.html">scripts</a> scrapeLakes.ts</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">24.52% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>26/106</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">18.66% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>14/75</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">25% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>3/12</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">25% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>23/92</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line low'></div>
|
|
||||||
<pre><table class="coverage">
|
|
||||||
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
||||||
<a name='L2'></a><a href='#L2'>2</a>
|
|
||||||
<a name='L3'></a><a href='#L3'>3</a>
|
|
||||||
<a name='L4'></a><a href='#L4'>4</a>
|
|
||||||
<a name='L5'></a><a href='#L5'>5</a>
|
|
||||||
<a name='L6'></a><a href='#L6'>6</a>
|
|
||||||
<a name='L7'></a><a href='#L7'>7</a>
|
|
||||||
<a name='L8'></a><a href='#L8'>8</a>
|
|
||||||
<a name='L9'></a><a href='#L9'>9</a>
|
|
||||||
<a name='L10'></a><a href='#L10'>10</a>
|
|
||||||
<a name='L11'></a><a href='#L11'>11</a>
|
|
||||||
<a name='L12'></a><a href='#L12'>12</a>
|
|
||||||
<a name='L13'></a><a href='#L13'>13</a>
|
|
||||||
<a name='L14'></a><a href='#L14'>14</a>
|
|
||||||
<a name='L15'></a><a href='#L15'>15</a>
|
|
||||||
<a name='L16'></a><a href='#L16'>16</a>
|
|
||||||
<a name='L17'></a><a href='#L17'>17</a>
|
|
||||||
<a name='L18'></a><a href='#L18'>18</a>
|
|
||||||
<a name='L19'></a><a href='#L19'>19</a>
|
|
||||||
<a name='L20'></a><a href='#L20'>20</a>
|
|
||||||
<a name='L21'></a><a href='#L21'>21</a>
|
|
||||||
<a name='L22'></a><a href='#L22'>22</a>
|
|
||||||
<a name='L23'></a><a href='#L23'>23</a>
|
|
||||||
<a name='L24'></a><a href='#L24'>24</a>
|
|
||||||
<a name='L25'></a><a href='#L25'>25</a>
|
|
||||||
<a name='L26'></a><a href='#L26'>26</a>
|
|
||||||
<a name='L27'></a><a href='#L27'>27</a>
|
|
||||||
<a name='L28'></a><a href='#L28'>28</a>
|
|
||||||
<a name='L29'></a><a href='#L29'>29</a>
|
|
||||||
<a name='L30'></a><a href='#L30'>30</a>
|
|
||||||
<a name='L31'></a><a href='#L31'>31</a>
|
|
||||||
<a name='L32'></a><a href='#L32'>32</a>
|
|
||||||
<a name='L33'></a><a href='#L33'>33</a>
|
|
||||||
<a name='L34'></a><a href='#L34'>34</a>
|
|
||||||
<a name='L35'></a><a href='#L35'>35</a>
|
|
||||||
<a name='L36'></a><a href='#L36'>36</a>
|
|
||||||
<a name='L37'></a><a href='#L37'>37</a>
|
|
||||||
<a name='L38'></a><a href='#L38'>38</a>
|
|
||||||
<a name='L39'></a><a href='#L39'>39</a>
|
|
||||||
<a name='L40'></a><a href='#L40'>40</a>
|
|
||||||
<a name='L41'></a><a href='#L41'>41</a>
|
|
||||||
<a name='L42'></a><a href='#L42'>42</a>
|
|
||||||
<a name='L43'></a><a href='#L43'>43</a>
|
|
||||||
<a name='L44'></a><a href='#L44'>44</a>
|
|
||||||
<a name='L45'></a><a href='#L45'>45</a>
|
|
||||||
<a name='L46'></a><a href='#L46'>46</a>
|
|
||||||
<a name='L47'></a><a href='#L47'>47</a>
|
|
||||||
<a name='L48'></a><a href='#L48'>48</a>
|
|
||||||
<a name='L49'></a><a href='#L49'>49</a>
|
|
||||||
<a name='L50'></a><a href='#L50'>50</a>
|
|
||||||
<a name='L51'></a><a href='#L51'>51</a>
|
|
||||||
<a name='L52'></a><a href='#L52'>52</a>
|
|
||||||
<a name='L53'></a><a href='#L53'>53</a>
|
|
||||||
<a name='L54'></a><a href='#L54'>54</a>
|
|
||||||
<a name='L55'></a><a href='#L55'>55</a>
|
|
||||||
<a name='L56'></a><a href='#L56'>56</a>
|
|
||||||
<a name='L57'></a><a href='#L57'>57</a>
|
|
||||||
<a name='L58'></a><a href='#L58'>58</a>
|
|
||||||
<a name='L59'></a><a href='#L59'>59</a>
|
|
||||||
<a name='L60'></a><a href='#L60'>60</a>
|
|
||||||
<a name='L61'></a><a href='#L61'>61</a>
|
|
||||||
<a name='L62'></a><a href='#L62'>62</a>
|
|
||||||
<a name='L63'></a><a href='#L63'>63</a>
|
|
||||||
<a name='L64'></a><a href='#L64'>64</a>
|
|
||||||
<a name='L65'></a><a href='#L65'>65</a>
|
|
||||||
<a name='L66'></a><a href='#L66'>66</a>
|
|
||||||
<a name='L67'></a><a href='#L67'>67</a>
|
|
||||||
<a name='L68'></a><a href='#L68'>68</a>
|
|
||||||
<a name='L69'></a><a href='#L69'>69</a>
|
|
||||||
<a name='L70'></a><a href='#L70'>70</a>
|
|
||||||
<a name='L71'></a><a href='#L71'>71</a>
|
|
||||||
<a name='L72'></a><a href='#L72'>72</a>
|
|
||||||
<a name='L73'></a><a href='#L73'>73</a>
|
|
||||||
<a name='L74'></a><a href='#L74'>74</a>
|
|
||||||
<a name='L75'></a><a href='#L75'>75</a>
|
|
||||||
<a name='L76'></a><a href='#L76'>76</a>
|
|
||||||
<a name='L77'></a><a href='#L77'>77</a>
|
|
||||||
<a name='L78'></a><a href='#L78'>78</a>
|
|
||||||
<a name='L79'></a><a href='#L79'>79</a>
|
|
||||||
<a name='L80'></a><a href='#L80'>80</a>
|
|
||||||
<a name='L81'></a><a href='#L81'>81</a>
|
|
||||||
<a name='L82'></a><a href='#L82'>82</a>
|
|
||||||
<a name='L83'></a><a href='#L83'>83</a>
|
|
||||||
<a name='L84'></a><a href='#L84'>84</a>
|
|
||||||
<a name='L85'></a><a href='#L85'>85</a>
|
|
||||||
<a name='L86'></a><a href='#L86'>86</a>
|
|
||||||
<a name='L87'></a><a href='#L87'>87</a>
|
|
||||||
<a name='L88'></a><a href='#L88'>88</a>
|
|
||||||
<a name='L89'></a><a href='#L89'>89</a>
|
|
||||||
<a name='L90'></a><a href='#L90'>90</a>
|
|
||||||
<a name='L91'></a><a href='#L91'>91</a>
|
|
||||||
<a name='L92'></a><a href='#L92'>92</a>
|
|
||||||
<a name='L93'></a><a href='#L93'>93</a>
|
|
||||||
<a name='L94'></a><a href='#L94'>94</a>
|
|
||||||
<a name='L95'></a><a href='#L95'>95</a>
|
|
||||||
<a name='L96'></a><a href='#L96'>96</a>
|
|
||||||
<a name='L97'></a><a href='#L97'>97</a>
|
|
||||||
<a name='L98'></a><a href='#L98'>98</a>
|
|
||||||
<a name='L99'></a><a href='#L99'>99</a>
|
|
||||||
<a name='L100'></a><a href='#L100'>100</a>
|
|
||||||
<a name='L101'></a><a href='#L101'>101</a>
|
|
||||||
<a name='L102'></a><a href='#L102'>102</a>
|
|
||||||
<a name='L103'></a><a href='#L103'>103</a>
|
|
||||||
<a name='L104'></a><a href='#L104'>104</a>
|
|
||||||
<a name='L105'></a><a href='#L105'>105</a>
|
|
||||||
<a name='L106'></a><a href='#L106'>106</a>
|
|
||||||
<a name='L107'></a><a href='#L107'>107</a>
|
|
||||||
<a name='L108'></a><a href='#L108'>108</a>
|
|
||||||
<a name='L109'></a><a href='#L109'>109</a>
|
|
||||||
<a name='L110'></a><a href='#L110'>110</a>
|
|
||||||
<a name='L111'></a><a href='#L111'>111</a>
|
|
||||||
<a name='L112'></a><a href='#L112'>112</a>
|
|
||||||
<a name='L113'></a><a href='#L113'>113</a>
|
|
||||||
<a name='L114'></a><a href='#L114'>114</a>
|
|
||||||
<a name='L115'></a><a href='#L115'>115</a>
|
|
||||||
<a name='L116'></a><a href='#L116'>116</a>
|
|
||||||
<a name='L117'></a><a href='#L117'>117</a>
|
|
||||||
<a name='L118'></a><a href='#L118'>118</a>
|
|
||||||
<a name='L119'></a><a href='#L119'>119</a>
|
|
||||||
<a name='L120'></a><a href='#L120'>120</a>
|
|
||||||
<a name='L121'></a><a href='#L121'>121</a>
|
|
||||||
<a name='L122'></a><a href='#L122'>122</a>
|
|
||||||
<a name='L123'></a><a href='#L123'>123</a>
|
|
||||||
<a name='L124'></a><a href='#L124'>124</a>
|
|
||||||
<a name='L125'></a><a href='#L125'>125</a>
|
|
||||||
<a name='L126'></a><a href='#L126'>126</a>
|
|
||||||
<a name='L127'></a><a href='#L127'>127</a>
|
|
||||||
<a name='L128'></a><a href='#L128'>128</a>
|
|
||||||
<a name='L129'></a><a href='#L129'>129</a>
|
|
||||||
<a name='L130'></a><a href='#L130'>130</a>
|
|
||||||
<a name='L131'></a><a href='#L131'>131</a>
|
|
||||||
<a name='L132'></a><a href='#L132'>132</a>
|
|
||||||
<a name='L133'></a><a href='#L133'>133</a>
|
|
||||||
<a name='L134'></a><a href='#L134'>134</a>
|
|
||||||
<a name='L135'></a><a href='#L135'>135</a>
|
|
||||||
<a name='L136'></a><a href='#L136'>136</a>
|
|
||||||
<a name='L137'></a><a href='#L137'>137</a>
|
|
||||||
<a name='L138'></a><a href='#L138'>138</a>
|
|
||||||
<a name='L139'></a><a href='#L139'>139</a>
|
|
||||||
<a name='L140'></a><a href='#L140'>140</a>
|
|
||||||
<a name='L141'></a><a href='#L141'>141</a>
|
|
||||||
<a name='L142'></a><a href='#L142'>142</a>
|
|
||||||
<a name='L143'></a><a href='#L143'>143</a>
|
|
||||||
<a name='L144'></a><a href='#L144'>144</a>
|
|
||||||
<a name='L145'></a><a href='#L145'>145</a>
|
|
||||||
<a name='L146'></a><a href='#L146'>146</a>
|
|
||||||
<a name='L147'></a><a href='#L147'>147</a>
|
|
||||||
<a name='L148'></a><a href='#L148'>148</a>
|
|
||||||
<a name='L149'></a><a href='#L149'>149</a>
|
|
||||||
<a name='L150'></a><a href='#L150'>150</a>
|
|
||||||
<a name='L151'></a><a href='#L151'>151</a>
|
|
||||||
<a name='L152'></a><a href='#L152'>152</a>
|
|
||||||
<a name='L153'></a><a href='#L153'>153</a>
|
|
||||||
<a name='L154'></a><a href='#L154'>154</a>
|
|
||||||
<a name='L155'></a><a href='#L155'>155</a>
|
|
||||||
<a name='L156'></a><a href='#L156'>156</a>
|
|
||||||
<a name='L157'></a><a href='#L157'>157</a>
|
|
||||||
<a name='L158'></a><a href='#L158'>158</a>
|
|
||||||
<a name='L159'></a><a href='#L159'>159</a>
|
|
||||||
<a name='L160'></a><a href='#L160'>160</a>
|
|
||||||
<a name='L161'></a><a href='#L161'>161</a>
|
|
||||||
<a name='L162'></a><a href='#L162'>162</a>
|
|
||||||
<a name='L163'></a><a href='#L163'>163</a>
|
|
||||||
<a name='L164'></a><a href='#L164'>164</a>
|
|
||||||
<a name='L165'></a><a href='#L165'>165</a>
|
|
||||||
<a name='L166'></a><a href='#L166'>166</a>
|
|
||||||
<a name='L167'></a><a href='#L167'>167</a>
|
|
||||||
<a name='L168'></a><a href='#L168'>168</a>
|
|
||||||
<a name='L169'></a><a href='#L169'>169</a>
|
|
||||||
<a name='L170'></a><a href='#L170'>170</a>
|
|
||||||
<a name='L171'></a><a href='#L171'>171</a>
|
|
||||||
<a name='L172'></a><a href='#L172'>172</a>
|
|
||||||
<a name='L173'></a><a href='#L173'>173</a>
|
|
||||||
<a name='L174'></a><a href='#L174'>174</a>
|
|
||||||
<a name='L175'></a><a href='#L175'>175</a>
|
|
||||||
<a name='L176'></a><a href='#L176'>176</a>
|
|
||||||
<a name='L177'></a><a href='#L177'>177</a>
|
|
||||||
<a name='L178'></a><a href='#L178'>178</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">7x</span>
|
|
||||||
<span class="cline-any cline-yes">7x</span>
|
|
||||||
<span class="cline-any cline-yes">4x</span>
|
|
||||||
<span class="cline-any cline-yes">4x</span>
|
|
||||||
<span class="cline-any cline-yes">4x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">4x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as cheerio from 'cheerio';
|
|
||||||
import axios from 'axios';
|
|
||||||
import https from 'https';
|
|
||||||
import { lakesConfig } from './lakesConfig';
|
|
||||||
|
|
||||||
interface DataRecord {
|
|
||||||
timestamp: string;
|
|
||||||
level: number;
|
|
||||||
flow: number;
|
|
||||||
inflow?: number;
|
|
||||||
volume?: number;
|
|
||||||
temperature?: number | null;
|
|
||||||
precipitation?: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse date from DD.MM.YYYY HH:MM to ISO
|
|
||||||
export function parseDateString(dateStr: string): string | null {
|
|
||||||
try {
|
|
||||||
if (!dateStr || !dateStr.includes(' ')) return null;
|
|
||||||
const [datePart, timePart] = dateStr.trim().split(' ');
|
|
||||||
const [day, month, year] = datePart.split('.');
|
|
||||||
const [hours, minutes] = timePart.split(':');
|
|
||||||
|
|
||||||
if (!year || !hours) return null;
|
|
||||||
|
|
||||||
const y = parseInt(year);
|
|
||||||
const m = parseInt(month) - 1;
|
|
||||||
const dDay = parseInt(day);
|
|
||||||
const d = new Date(y, m, dDay, parseInt(hours), parseInt(minutes));
|
|
||||||
<span class="missing-if-branch" title="if path not taken" >I</span>if (isNaN(d.getTime())) <span class="cstat-no" title="statement not covered" >return null;</span>
|
|
||||||
if (d.getFullYear() !== y || d.getMonth() !== m || d.getDate() !== dDay) return null;
|
|
||||||
return d.toISOString();
|
|
||||||
} catch (e) {
|
|
||||||
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function scrapeLake(lakeId: string, oid: string, internalId: string) {
|
|
||||||
const URL = `https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?oid=${oid}&id=${internalId}`;
|
|
||||||
const DATA_FILE = path.resolve(`public/data/${internalId}.json`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const agent = new https.Agent({ rejectUnauthorized: false });
|
|
||||||
const response = await axios.get(URL, {
|
|
||||||
httpsAgent: agent,
|
|
||||||
headers: {
|
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const $ = <span class="cstat-no" title="statement not covered" >cheerio.load(response.data);</span>
|
|
||||||
|
|
||||||
let currentInflow = <span class="cstat-no" title="statement not covered" >0;</span>
|
|
||||||
let currentVolume = <span class="cstat-no" title="statement not covered" >0;</span>
|
|
||||||
let currentTemp: number | null = <span class="cstat-no" title="statement not covered" >null;</span>
|
|
||||||
let currentPrecip: number | null = <span class="cstat-no" title="statement not covered" >null;</span>
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > $('table').each(<span class="fstat-no" title="function not covered" >(i</span>, tbl) => {</span>
|
|
||||||
const text = <span class="cstat-no" title="statement not covered" >$(tbl).text();</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (text.includes('Aktuální hodnoty') && text.includes('Přítok')) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > $(tbl).find('tr').each(<span class="fstat-no" title="function not covered" >(j</span>, r) => {</span>
|
|
||||||
const label = <span class="cstat-no" title="statement not covered" >$(r).find('td').eq(0).text().trim();</span>
|
|
||||||
const valStr = <span class="cstat-no" title="statement not covered" >$(r).find('td').eq(1).text().trim().replace(/\s/g, '').replace(',', '.');</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (label.includes('Přítok')) <span class="cstat-no" title="statement not covered" >currentInflow = parseFloat(valStr) || 0;</span></span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (label.includes('Objem')) <span class="cstat-no" title="statement not covered" >currentVolume = parseFloat(valStr) || 0;</span></span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (label.includes('Teplota')) {</span>
|
|
||||||
const v = <span class="cstat-no" title="statement not covered" >parseFloat(valStr);</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (!isNaN(v)) <span class="cstat-no" title="statement not covered" >currentTemp = v;</span></span>
|
|
||||||
}
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (label.includes('Srážky')) {</span>
|
|
||||||
const v = <span class="cstat-no" title="statement not covered" >parseFloat(valStr);</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (!isNaN(v)) <span class="cstat-no" title="statement not covered" >currentPrecip = v;</span></span>
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const records: DataRecord[] = <span class="cstat-no" title="statement not covered" >[];</span>
|
|
||||||
let dataTable = <span class="cstat-no" title="statement not covered" >null;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > $('table').each(<span class="fstat-no" title="function not covered" >(i</span>, tbl) => {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > dataTable = $(tbl);</span>
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (dataTable) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > dataTable.find('tr').each(<span class="fstat-no" title="function not covered" >(i</span>, row) => {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (i === 0) <span class="cstat-no" title="statement not covered" >return; // skip header</span></span>
|
|
||||||
const cols = <span class="cstat-no" title="statement not covered" >$(row).find('td');</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (cols.length >= 3) {</span>
|
|
||||||
const rawDate = <span class="cstat-no" title="statement not covered" >$(cols[0]).text().trim(); </span>
|
|
||||||
const levelStr = <span class="cstat-no" title="statement not covered" >$(cols[1]).text().trim().replace(',', '.');</span>
|
|
||||||
let flowStr = <span class="cstat-no" title="statement not covered" >$(cols[2]).text().trim().replace(',', '.');</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (flowStr === '' && cols.length >= 4) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > flowStr = $(cols[3]).text().trim().replace(',', '.');</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsedDateStr = <span class="cstat-no" title="statement not covered" >parseDateString(rawDate);</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (parsedDateStr) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > records.push({</span>
|
|
||||||
timestamp: parsedDateStr,
|
|
||||||
level: parseFloat(levelStr) || 0,
|
|
||||||
flow: parseFloat(flowStr) || 0,
|
|
||||||
inflow: 0,
|
|
||||||
volume: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (records.length > 0) {</span>
|
|
||||||
// Apply current values to the latest record
|
|
||||||
<span class="cstat-no" title="statement not covered" > records[0].inflow = currentInflow;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > records[0].volume = currentVolume;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (currentTemp !== null) <span class="cstat-no" title="statement not covered" >records[0].temperature = currentTemp;</span></span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (currentPrecip !== null) <span class="cstat-no" title="statement not covered" >records[0].precipitation = currentPrecip;</span></span>
|
|
||||||
}
|
|
||||||
|
|
||||||
let existingData: DataRecord[] = <span class="cstat-no" title="statement not covered" >[];</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (fs.existsSync(DATA_FILE)) {</span>
|
|
||||||
const fileContent = <span class="cstat-no" title="statement not covered" >fs.readFileSync(DATA_FILE, 'utf-8');</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > existingData = JSON.parse(fileContent);</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
const dataMap = <span class="cstat-no" title="statement not covered" >new Map<string, DataRecord>();</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > existingData.forEach(<span class="fstat-no" title="function not covered" >item => <span class="cstat-no" title="statement not covered" >d</span>ataMap.set(item.timestamp, item))</span>;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > records.forEach(<span class="fstat-no" title="function not covered" >item => <span class="cstat-no" title="statement not covered" >d</span>ataMap.set(item.timestamp, item))</span>;</span>
|
|
||||||
|
|
||||||
const mergedData = <span class="cstat-no" title="statement not covered" >Array.from(dataMap.values()).sort(<span class="fstat-no" title="function not covered" >(a</span>, b) => {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();</span>
|
|
||||||
});
|
|
||||||
|
|
||||||
// Propagate previous values if missing (user requested)
|
|
||||||
let lastKnownTemp: number | null = <span class="cstat-no" title="statement not covered" >null;</span>
|
|
||||||
let lastKnownPrecip: number | null = <span class="cstat-no" title="statement not covered" >null;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > mergedData.forEach(<span class="fstat-no" title="function not covered" >item => {</span></span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (item.temperature !== undefined && item.temperature !== null) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > lastKnownTemp = item.temperature;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > } else if (lastKnownTemp !== null) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > item.temperature = lastKnownTemp;</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > if (item.precipitation !== undefined && item.precipitation !== null) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > lastKnownPrecip = item.precipitation;</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > } else if (lastKnownPrecip !== null) {</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > item.precipitation = lastKnownPrecip;</span>
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > fs.mkdirSync(path.dirname(DATA_FILE), { recursive: true });</span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > fs.writeFileSync(DATA_FILE, JSON.stringify(mergedData, null, 2), 'utf-8');</span>
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > console.log(`[${internalId}] Scraped ${records.length} records. DB total: ${mergedData.length}`);</span>
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
<span class="cstat-no" title="statement not covered" > console.error(`[${internalId}] Error scraping data:`, error.message);</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runScraper() {
|
|
||||||
console.log(`Starting bulk scraper for ${lakesConfig.length} lakes...`);
|
|
||||||
|
|
||||||
for (const lake of lakesConfig) {
|
|
||||||
// ID format: VLL1|1 -> internalId=VLL1, oid=1
|
|
||||||
const [internalId, oid] = lake.id.split('|');
|
|
||||||
await scrapeLake(lake.id, oid, internalId);
|
|
||||||
// Add small delay to not hammer the server
|
|
||||||
<span class="cstat-no" title="statement not covered" > await new Promise(<span class="fstat-no" title="function not covered" >resolve => <span class="cstat-no" title="statement not covered" >s</span>etTimeout(resolve, 500))</span>;</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="cstat-no" title="statement not covered" > console.log('Bulk scraping finished.');</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
runScraper();
|
|
||||||
</pre></td></tr></table></pre>
|
|
||||||
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../sorter.js"></script>
|
|
||||||
<script src="../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 138 B |
@@ -1,210 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
var addSorting = (function() {
|
|
||||||
'use strict';
|
|
||||||
var cols,
|
|
||||||
currentSort = {
|
|
||||||
index: 0,
|
|
||||||
desc: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// returns the summary table element
|
|
||||||
function getTable() {
|
|
||||||
return document.querySelector('.coverage-summary');
|
|
||||||
}
|
|
||||||
// returns the thead element of the summary table
|
|
||||||
function getTableHeader() {
|
|
||||||
return getTable().querySelector('thead tr');
|
|
||||||
}
|
|
||||||
// returns the tbody element of the summary table
|
|
||||||
function getTableBody() {
|
|
||||||
return getTable().querySelector('tbody');
|
|
||||||
}
|
|
||||||
// returns the th element for nth column
|
|
||||||
function getNthColumn(n) {
|
|
||||||
return getTableHeader().querySelectorAll('th')[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFilterInput() {
|
|
||||||
const searchValue = document.getElementById('fileSearch').value;
|
|
||||||
const rows = document.getElementsByTagName('tbody')[0].children;
|
|
||||||
|
|
||||||
// Try to create a RegExp from the searchValue. If it fails (invalid regex),
|
|
||||||
// it will be treated as a plain text search
|
|
||||||
let searchRegex;
|
|
||||||
try {
|
|
||||||
searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive
|
|
||||||
} catch (error) {
|
|
||||||
searchRegex = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const row = rows[i];
|
|
||||||
let isMatch = false;
|
|
||||||
|
|
||||||
if (searchRegex) {
|
|
||||||
// If a valid regex was created, use it for matching
|
|
||||||
isMatch = searchRegex.test(row.textContent);
|
|
||||||
} else {
|
|
||||||
// Otherwise, fall back to the original plain text search
|
|
||||||
isMatch = row.textContent
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchValue.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
row.style.display = isMatch ? '' : 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// loads the search box
|
|
||||||
function addSearchBox() {
|
|
||||||
var template = document.getElementById('filterTemplate');
|
|
||||||
var templateClone = template.content.cloneNode(true);
|
|
||||||
templateClone.getElementById('fileSearch').oninput = onFilterInput;
|
|
||||||
template.parentElement.appendChild(templateClone);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loads all columns
|
|
||||||
function loadColumns() {
|
|
||||||
var colNodes = getTableHeader().querySelectorAll('th'),
|
|
||||||
colNode,
|
|
||||||
cols = [],
|
|
||||||
col,
|
|
||||||
i;
|
|
||||||
|
|
||||||
for (i = 0; i < colNodes.length; i += 1) {
|
|
||||||
colNode = colNodes[i];
|
|
||||||
col = {
|
|
||||||
key: colNode.getAttribute('data-col'),
|
|
||||||
sortable: !colNode.getAttribute('data-nosort'),
|
|
||||||
type: colNode.getAttribute('data-type') || 'string'
|
|
||||||
};
|
|
||||||
cols.push(col);
|
|
||||||
if (col.sortable) {
|
|
||||||
col.defaultDescSort = col.type === 'number';
|
|
||||||
colNode.innerHTML =
|
|
||||||
colNode.innerHTML + '<span class="sorter"></span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cols;
|
|
||||||
}
|
|
||||||
// attaches a data attribute to every tr element with an object
|
|
||||||
// of data values keyed by column name
|
|
||||||
function loadRowData(tableRow) {
|
|
||||||
var tableCols = tableRow.querySelectorAll('td'),
|
|
||||||
colNode,
|
|
||||||
col,
|
|
||||||
data = {},
|
|
||||||
i,
|
|
||||||
val;
|
|
||||||
for (i = 0; i < tableCols.length; i += 1) {
|
|
||||||
colNode = tableCols[i];
|
|
||||||
col = cols[i];
|
|
||||||
val = colNode.getAttribute('data-value');
|
|
||||||
if (col.type === 'number') {
|
|
||||||
val = Number(val);
|
|
||||||
}
|
|
||||||
data[col.key] = val;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
// loads all row data
|
|
||||||
function loadData() {
|
|
||||||
var rows = getTableBody().querySelectorAll('tr'),
|
|
||||||
i;
|
|
||||||
|
|
||||||
for (i = 0; i < rows.length; i += 1) {
|
|
||||||
rows[i].data = loadRowData(rows[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sorts the table using the data for the ith column
|
|
||||||
function sortByIndex(index, desc) {
|
|
||||||
var key = cols[index].key,
|
|
||||||
sorter = function(a, b) {
|
|
||||||
a = a.data[key];
|
|
||||||
b = b.data[key];
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
},
|
|
||||||
finalSorter = sorter,
|
|
||||||
tableBody = document.querySelector('.coverage-summary tbody'),
|
|
||||||
rowNodes = tableBody.querySelectorAll('tr'),
|
|
||||||
rows = [],
|
|
||||||
i;
|
|
||||||
|
|
||||||
if (desc) {
|
|
||||||
finalSorter = function(a, b) {
|
|
||||||
return -1 * sorter(a, b);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < rowNodes.length; i += 1) {
|
|
||||||
rows.push(rowNodes[i]);
|
|
||||||
tableBody.removeChild(rowNodes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rows.sort(finalSorter);
|
|
||||||
|
|
||||||
for (i = 0; i < rows.length; i += 1) {
|
|
||||||
tableBody.appendChild(rows[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// removes sort indicators for current column being sorted
|
|
||||||
function removeSortIndicators() {
|
|
||||||
var col = getNthColumn(currentSort.index),
|
|
||||||
cls = col.className;
|
|
||||||
|
|
||||||
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
|
|
||||||
col.className = cls;
|
|
||||||
}
|
|
||||||
// adds sort indicators for current column being sorted
|
|
||||||
function addSortIndicators() {
|
|
||||||
getNthColumn(currentSort.index).className += currentSort.desc
|
|
||||||
? ' sorted-desc'
|
|
||||||
: ' sorted';
|
|
||||||
}
|
|
||||||
// adds event listeners for all sorter widgets
|
|
||||||
function enableUI() {
|
|
||||||
var i,
|
|
||||||
el,
|
|
||||||
ithSorter = function ithSorter(i) {
|
|
||||||
var col = cols[i];
|
|
||||||
|
|
||||||
return function() {
|
|
||||||
var desc = col.defaultDescSort;
|
|
||||||
|
|
||||||
if (currentSort.index === i) {
|
|
||||||
desc = !currentSort.desc;
|
|
||||||
}
|
|
||||||
sortByIndex(i, desc);
|
|
||||||
removeSortIndicators();
|
|
||||||
currentSort.index = i;
|
|
||||||
currentSort.desc = desc;
|
|
||||||
addSortIndicators();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
for (i = 0; i < cols.length; i += 1) {
|
|
||||||
if (cols[i].sortable) {
|
|
||||||
// add the click event handler on the th so users
|
|
||||||
// dont have to click on those tiny arrows
|
|
||||||
el = getNthColumn(i).querySelector('.sorter').parentElement;
|
|
||||||
if (el.addEventListener) {
|
|
||||||
el.addEventListener('click', ithSorter(i));
|
|
||||||
} else {
|
|
||||||
el.attachEvent('onclick', ithSorter(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// adds sorting functionality to the UI
|
|
||||||
return function() {
|
|
||||||
if (!getTable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cols = loadColumns();
|
|
||||||
loadData();
|
|
||||||
addSearchBox();
|
|
||||||
addSortIndicators();
|
|
||||||
enableUI();
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
window.addEventListener('load', addSorting);
|
|
||||||
@@ -1,466 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for src/components/KpiCards.tsx</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/components</a> KpiCards.tsx</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">53.84% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>7/13</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">65.21% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>15/23</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">33.33% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>2/6</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">58.33% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>7/12</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line medium'></div>
|
|
||||||
<pre><table class="coverage">
|
|
||||||
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
||||||
<a name='L2'></a><a href='#L2'>2</a>
|
|
||||||
<a name='L3'></a><a href='#L3'>3</a>
|
|
||||||
<a name='L4'></a><a href='#L4'>4</a>
|
|
||||||
<a name='L5'></a><a href='#L5'>5</a>
|
|
||||||
<a name='L6'></a><a href='#L6'>6</a>
|
|
||||||
<a name='L7'></a><a href='#L7'>7</a>
|
|
||||||
<a name='L8'></a><a href='#L8'>8</a>
|
|
||||||
<a name='L9'></a><a href='#L9'>9</a>
|
|
||||||
<a name='L10'></a><a href='#L10'>10</a>
|
|
||||||
<a name='L11'></a><a href='#L11'>11</a>
|
|
||||||
<a name='L12'></a><a href='#L12'>12</a>
|
|
||||||
<a name='L13'></a><a href='#L13'>13</a>
|
|
||||||
<a name='L14'></a><a href='#L14'>14</a>
|
|
||||||
<a name='L15'></a><a href='#L15'>15</a>
|
|
||||||
<a name='L16'></a><a href='#L16'>16</a>
|
|
||||||
<a name='L17'></a><a href='#L17'>17</a>
|
|
||||||
<a name='L18'></a><a href='#L18'>18</a>
|
|
||||||
<a name='L19'></a><a href='#L19'>19</a>
|
|
||||||
<a name='L20'></a><a href='#L20'>20</a>
|
|
||||||
<a name='L21'></a><a href='#L21'>21</a>
|
|
||||||
<a name='L22'></a><a href='#L22'>22</a>
|
|
||||||
<a name='L23'></a><a href='#L23'>23</a>
|
|
||||||
<a name='L24'></a><a href='#L24'>24</a>
|
|
||||||
<a name='L25'></a><a href='#L25'>25</a>
|
|
||||||
<a name='L26'></a><a href='#L26'>26</a>
|
|
||||||
<a name='L27'></a><a href='#L27'>27</a>
|
|
||||||
<a name='L28'></a><a href='#L28'>28</a>
|
|
||||||
<a name='L29'></a><a href='#L29'>29</a>
|
|
||||||
<a name='L30'></a><a href='#L30'>30</a>
|
|
||||||
<a name='L31'></a><a href='#L31'>31</a>
|
|
||||||
<a name='L32'></a><a href='#L32'>32</a>
|
|
||||||
<a name='L33'></a><a href='#L33'>33</a>
|
|
||||||
<a name='L34'></a><a href='#L34'>34</a>
|
|
||||||
<a name='L35'></a><a href='#L35'>35</a>
|
|
||||||
<a name='L36'></a><a href='#L36'>36</a>
|
|
||||||
<a name='L37'></a><a href='#L37'>37</a>
|
|
||||||
<a name='L38'></a><a href='#L38'>38</a>
|
|
||||||
<a name='L39'></a><a href='#L39'>39</a>
|
|
||||||
<a name='L40'></a><a href='#L40'>40</a>
|
|
||||||
<a name='L41'></a><a href='#L41'>41</a>
|
|
||||||
<a name='L42'></a><a href='#L42'>42</a>
|
|
||||||
<a name='L43'></a><a href='#L43'>43</a>
|
|
||||||
<a name='L44'></a><a href='#L44'>44</a>
|
|
||||||
<a name='L45'></a><a href='#L45'>45</a>
|
|
||||||
<a name='L46'></a><a href='#L46'>46</a>
|
|
||||||
<a name='L47'></a><a href='#L47'>47</a>
|
|
||||||
<a name='L48'></a><a href='#L48'>48</a>
|
|
||||||
<a name='L49'></a><a href='#L49'>49</a>
|
|
||||||
<a name='L50'></a><a href='#L50'>50</a>
|
|
||||||
<a name='L51'></a><a href='#L51'>51</a>
|
|
||||||
<a name='L52'></a><a href='#L52'>52</a>
|
|
||||||
<a name='L53'></a><a href='#L53'>53</a>
|
|
||||||
<a name='L54'></a><a href='#L54'>54</a>
|
|
||||||
<a name='L55'></a><a href='#L55'>55</a>
|
|
||||||
<a name='L56'></a><a href='#L56'>56</a>
|
|
||||||
<a name='L57'></a><a href='#L57'>57</a>
|
|
||||||
<a name='L58'></a><a href='#L58'>58</a>
|
|
||||||
<a name='L59'></a><a href='#L59'>59</a>
|
|
||||||
<a name='L60'></a><a href='#L60'>60</a>
|
|
||||||
<a name='L61'></a><a href='#L61'>61</a>
|
|
||||||
<a name='L62'></a><a href='#L62'>62</a>
|
|
||||||
<a name='L63'></a><a href='#L63'>63</a>
|
|
||||||
<a name='L64'></a><a href='#L64'>64</a>
|
|
||||||
<a name='L65'></a><a href='#L65'>65</a>
|
|
||||||
<a name='L66'></a><a href='#L66'>66</a>
|
|
||||||
<a name='L67'></a><a href='#L67'>67</a>
|
|
||||||
<a name='L68'></a><a href='#L68'>68</a>
|
|
||||||
<a name='L69'></a><a href='#L69'>69</a>
|
|
||||||
<a name='L70'></a><a href='#L70'>70</a>
|
|
||||||
<a name='L71'></a><a href='#L71'>71</a>
|
|
||||||
<a name='L72'></a><a href='#L72'>72</a>
|
|
||||||
<a name='L73'></a><a href='#L73'>73</a>
|
|
||||||
<a name='L74'></a><a href='#L74'>74</a>
|
|
||||||
<a name='L75'></a><a href='#L75'>75</a>
|
|
||||||
<a name='L76'></a><a href='#L76'>76</a>
|
|
||||||
<a name='L77'></a><a href='#L77'>77</a>
|
|
||||||
<a name='L78'></a><a href='#L78'>78</a>
|
|
||||||
<a name='L79'></a><a href='#L79'>79</a>
|
|
||||||
<a name='L80'></a><a href='#L80'>80</a>
|
|
||||||
<a name='L81'></a><a href='#L81'>81</a>
|
|
||||||
<a name='L82'></a><a href='#L82'>82</a>
|
|
||||||
<a name='L83'></a><a href='#L83'>83</a>
|
|
||||||
<a name='L84'></a><a href='#L84'>84</a>
|
|
||||||
<a name='L85'></a><a href='#L85'>85</a>
|
|
||||||
<a name='L86'></a><a href='#L86'>86</a>
|
|
||||||
<a name='L87'></a><a href='#L87'>87</a>
|
|
||||||
<a name='L88'></a><a href='#L88'>88</a>
|
|
||||||
<a name='L89'></a><a href='#L89'>89</a>
|
|
||||||
<a name='L90'></a><a href='#L90'>90</a>
|
|
||||||
<a name='L91'></a><a href='#L91'>91</a>
|
|
||||||
<a name='L92'></a><a href='#L92'>92</a>
|
|
||||||
<a name='L93'></a><a href='#L93'>93</a>
|
|
||||||
<a name='L94'></a><a href='#L94'>94</a>
|
|
||||||
<a name='L95'></a><a href='#L95'>95</a>
|
|
||||||
<a name='L96'></a><a href='#L96'>96</a>
|
|
||||||
<a name='L97'></a><a href='#L97'>97</a>
|
|
||||||
<a name='L98'></a><a href='#L98'>98</a>
|
|
||||||
<a name='L99'></a><a href='#L99'>99</a>
|
|
||||||
<a name='L100'></a><a href='#L100'>100</a>
|
|
||||||
<a name='L101'></a><a href='#L101'>101</a>
|
|
||||||
<a name='L102'></a><a href='#L102'>102</a>
|
|
||||||
<a name='L103'></a><a href='#L103'>103</a>
|
|
||||||
<a name='L104'></a><a href='#L104'>104</a>
|
|
||||||
<a name='L105'></a><a href='#L105'>105</a>
|
|
||||||
<a name='L106'></a><a href='#L106'>106</a>
|
|
||||||
<a name='L107'></a><a href='#L107'>107</a>
|
|
||||||
<a name='L108'></a><a href='#L108'>108</a>
|
|
||||||
<a name='L109'></a><a href='#L109'>109</a>
|
|
||||||
<a name='L110'></a><a href='#L110'>110</a>
|
|
||||||
<a name='L111'></a><a href='#L111'>111</a>
|
|
||||||
<a name='L112'></a><a href='#L112'>112</a>
|
|
||||||
<a name='L113'></a><a href='#L113'>113</a>
|
|
||||||
<a name='L114'></a><a href='#L114'>114</a>
|
|
||||||
<a name='L115'></a><a href='#L115'>115</a>
|
|
||||||
<a name='L116'></a><a href='#L116'>116</a>
|
|
||||||
<a name='L117'></a><a href='#L117'>117</a>
|
|
||||||
<a name='L118'></a><a href='#L118'>118</a>
|
|
||||||
<a name='L119'></a><a href='#L119'>119</a>
|
|
||||||
<a name='L120'></a><a href='#L120'>120</a>
|
|
||||||
<a name='L121'></a><a href='#L121'>121</a>
|
|
||||||
<a name='L122'></a><a href='#L122'>122</a>
|
|
||||||
<a name='L123'></a><a href='#L123'>123</a>
|
|
||||||
<a name='L124'></a><a href='#L124'>124</a>
|
|
||||||
<a name='L125'></a><a href='#L125'>125</a>
|
|
||||||
<a name='L126'></a><a href='#L126'>126</a>
|
|
||||||
<a name='L127'></a><a href='#L127'>127</a>
|
|
||||||
<a name='L128'></a><a href='#L128'>128</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">1x</span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">3x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-no"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { FiArrowUp, FiArrowDown } from 'react-icons/fi';
|
|
||||||
import { type Language, t } from '../translations';
|
|
||||||
import { useState, useEffect } from 'react';
|
|
||||||
|
|
||||||
interface KpiData {
|
|
||||||
level: number;
|
|
||||||
inflow: number;
|
|
||||||
outflow: number;
|
|
||||||
outflow: number;
|
|
||||||
volume: number;
|
|
||||||
fullness: number;
|
|
||||||
storageDiff?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
data: KpiData;
|
|
||||||
language: Language;
|
|
||||||
lakeName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const KpiCards = ({ data, language, lakeName = 'Lipno 1' }: Props) => {
|
|
||||||
const [showTooltip, setShowTooltip] = useState(false);
|
|
||||||
const dict = t[language].kpi;
|
|
||||||
const flowDiff = data.inflow - data.outflow;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
<span class="missing-if-branch" title="if path not taken" >I</span>if (showTooltip) {
|
|
||||||
const timer = <span class="cstat-no" title="statement not covered" >setTimeout(<span class="fstat-no" title="function not covered" >() => {</span></span>
|
|
||||||
<span class="cstat-no" title="statement not covered" > setShowTooltip(false);</span>
|
|
||||||
}, 3500);
|
|
||||||
<span class="cstat-no" title="statement not covered" > return <span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >c</span>learTimeout(timer);</span></span>
|
|
||||||
}
|
|
||||||
}, [showTooltip]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="kpi-grid-container">
|
|
||||||
{/* CARD 1: HLADINA */}
|
|
||||||
<div className="kpi-card">
|
|
||||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem' }}>
|
|
||||||
{dict.level} {lakeName}
|
|
||||||
</div>
|
|
||||||
<div style={{ fontSize: '2.5rem', fontWeight: 'bold', color: 'var(--color-cyan)', lineHeight: 1, marginBottom: '0.5rem' }}>
|
|
||||||
{data.level.toFixed(2)} <span style={{ fontSize: '1rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>m n. m.</span>
|
|
||||||
</div>
|
|
||||||
<div style={{ fontSize: '0.85rem', color: 'var(--color-green)' }}>
|
|
||||||
(+0.02 m / 24h)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Decorative Circle for Level */}
|
|
||||||
<div style={{ position: 'absolute', right: '1.5rem', top: '1.5rem', width: '40px', height: '40px', borderRadius: '50%', border: '4px solid rgba(0, 195, 255, 0.2)', borderTopColor: 'var(--color-cyan)', transform: 'rotate(45deg)' }}></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* CARD 2: PRŮTOK */}
|
|
||||||
<div className="kpi-card">
|
|
||||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem' }}>
|
|
||||||
{dict.flow}
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', height: '100%' }}>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.85rem' }}>
|
|
||||||
<div style={{ fontSize: '0.85rem', color: 'var(--text-muted)', display: 'flex', alignItems: 'center' }}>
|
|
||||||
<span style={{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', backgroundColor: '#8b5cf6', marginRight: '6px' }}></span>
|
|
||||||
{dict.inflow}: <span style={{ fontWeight: 'bold', color: 'var(--text-main)', marginLeft: '4px' }}>{data.inflow.toFixed(1)} m³/s</span>
|
|
||||||
</div>
|
|
||||||
<div style={{ fontSize: '0.85rem', color: 'var(--text-muted)', marginTop: '0.25rem', display: 'flex', alignItems: 'center', gap: '0.25rem' }}>
|
|
||||||
<span style={{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', backgroundColor: 'var(--color-orange)', marginRight: '2px' }}></span>
|
|
||||||
{dict.outflow}: <span style={{ fontWeight: 'bold', color: 'var(--text-main)' }}>{data.outflow.toFixed(1)} m³/s</span>
|
|
||||||
{flowDiff > 0 ? <FiArrowUp color="var(--color-green)" /> : <span class="branch-1 cbranch-no" title="branch not covered" >flowDiff < 0 ? <FiArrowDown color="var(--color-red)" /> : null}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Flow Circle */}
|
|
||||||
<div style={{ width: '40px', height: '40px', borderRadius: '50%', border: '4px solid rgba(0, 195, 255, 0.2)', borderTopColor: 'var(--color-cyan)', borderRightColor: 'var(--color-cyan)', display: 'flex', alignItems: 'center', justifyContent: 'center', transform: 'rotate(-45deg)' }}>
|
|
||||||
<span style={{ fontSize: '0.65rem', transform: 'rotate(45deg)', color: 'var(--text-main)', fontWeight: 'bold' }}>
|
|
||||||
<div style={{ lineHeight: 1 }}>{data.outflow.toFixed(1)}</div>
|
|
||||||
<div style={{ fontSize: '0.45rem', opacity: 0.7 }}>m³/s</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* CARD 3: NAPLNĚNOST */}
|
|
||||||
<div className="kpi-card">
|
|
||||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '0.5rem', display: 'flex', alignItems: 'center', gap: '0.4rem', position: 'relative' }}>
|
|
||||||
{dict.fullness}
|
|
||||||
<span
|
|
||||||
onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etShowTooltip(!showTooltip)}</span>
|
|
||||||
style={{ cursor: 'pointer', fontSize: '0.85rem', opacity: 0.6, padding: '0 4px' }}
|
|
||||||
>
|
|
||||||
ⓘ
|
|
||||||
</span>
|
|
||||||
{showTooltip && (
|
|
||||||
<span class="branch-1 cbranch-no" title="branch not covered" > <div </span>
|
|
||||||
onClick={<span class="fstat-no" title="function not covered" >() => <span class="cstat-no" title="statement not covered" >s</span>etShowTooltip(false)}</span>
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
bottom: '100%',
|
|
||||||
left: '50%',
|
|
||||||
transform: 'translateX(-50%)',
|
|
||||||
marginBottom: '8px',
|
|
||||||
backgroundColor: 'var(--bg-card)',
|
|
||||||
border: '1px solid var(--border-color)',
|
|
||||||
padding: '0.75rem',
|
|
||||||
borderRadius: '8px',
|
|
||||||
width: '250px',
|
|
||||||
zIndex: 100,
|
|
||||||
boxShadow: '0 4px 12px rgba(0,0,0,0.5)',
|
|
||||||
color: 'var(--text-main)',
|
|
||||||
fontSize: '0.85rem',
|
|
||||||
lineHeight: 1.4,
|
|
||||||
cursor: 'pointer'
|
|
||||||
}}>
|
|
||||||
{language === 'cs' ? "Rozdíl mezi aktuální hladinou a hladinou zásobního prostoru (důležité pro jachtaře a rekreaci)." : "Difference between current water level and storage space level (important for sailing and recreation)."}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div style={{ fontSize: '2rem', fontWeight: 'bold', lineHeight: 1, marginBottom: '0.5rem', color: data.storageDiff && data.storageDiff < 0 ? 'var(--color-red)' : 'var(--color-cyan)' }}>
|
|
||||||
{data.storageDiff !== undefined && data.storageDiff !== 0 ? (data.storageDiff > 0 ? `+${data.storageDiff.toFixed(2)} m` : `${data.storageDiff.toFixed(2)} m`) : (data.fullness > 0 ? `${data.fullness.toFixed(1)}%` : <span class="branch-1 cbranch-no" title="branch not covered" >'N/A')}</span>
|
|
||||||
</div>
|
|
||||||
<div style={{ fontSize: '0.85rem', color: 'var(--text-muted)' }}>
|
|
||||||
{dict.volume}: {data.volume.toFixed(1)} mil. m³
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default KpiCards;
|
|
||||||
</pre></td></tr></table></pre>
|
|
||||||
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../../sorter.js"></script>
|
|
||||||
<script src="../../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for src/components</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../../index.html">All files</a> src/components</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">53.84% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>7/13</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">65.21% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>15/23</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">33.33% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>2/6</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">58.33% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>7/12</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line medium'></div>
|
|
||||||
<div class="pad1">
|
|
||||||
<table class="coverage-summary">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
|
||||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
|
||||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
|
||||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
|
||||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
|
||||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
|
||||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody><tr>
|
|
||||||
<td class="file medium" data-value="KpiCards.tsx"><a href="KpiCards.tsx.html">KpiCards.tsx</a></td>
|
|
||||||
<td data-value="53.84" class="pic medium">
|
|
||||||
<div class="chart"><div class="cover-fill" style="width: 53%"></div><div class="cover-empty" style="width: 47%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="53.84" class="pct medium">53.84%</td>
|
|
||||||
<td data-value="13" class="abs medium">7/13</td>
|
|
||||||
<td data-value="65.21" class="pct medium">65.21%</td>
|
|
||||||
<td data-value="23" class="abs medium">15/23</td>
|
|
||||||
<td data-value="33.33" class="pct low">33.33%</td>
|
|
||||||
<td data-value="6" class="abs low">2/6</td>
|
|
||||||
<td data-value="58.33" class="pct medium">58.33%</td>
|
|
||||||
<td data-value="12" class="abs medium">7/12</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../../sorter.js"></script>
|
|
||||||
<script src="../../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for src</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../index.html">All files</a> src</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line high'></div>
|
|
||||||
<div class="pad1">
|
|
||||||
<table class="coverage-summary">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
|
||||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
|
||||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
|
||||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
|
||||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
|
||||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
|
||||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody><tr>
|
|
||||||
<td class="file high" data-value="translations.ts"><a href="translations.ts.html">translations.ts</a></td>
|
|
||||||
<td data-value="100" class="pic high">
|
|
||||||
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
|
||||||
</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="0" class="abs high">0/0</td>
|
|
||||||
<td data-value="100" class="pct high">100%</td>
|
|
||||||
<td data-value="1" class="abs high">1/1</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../sorter.js"></script>
|
|
||||||
<script src="../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
@@ -1,385 +0,0 @@
|
|||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Code coverage report for src/translations.ts</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="../prettify.css" />
|
|
||||||
<link rel="stylesheet" href="../base.css" />
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<style type='text/css'>
|
|
||||||
.coverage-summary .sorter {
|
|
||||||
background-image: url(../sort-arrow-sprite.png);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class='wrapper'>
|
|
||||||
<div class='pad1'>
|
|
||||||
<h1><a href="../index.html">All files</a> / <a href="index.html">src</a> translations.ts</h1>
|
|
||||||
<div class='clearfix'>
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Statements</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Branches</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Functions</span>
|
|
||||||
<span class='fraction'>0/0</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class='fl pad1y space-right2'>
|
|
||||||
<span class="strong">100% </span>
|
|
||||||
<span class="quiet">Lines</span>
|
|
||||||
<span class='fraction'>1/1</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<p class="quiet">
|
|
||||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
||||||
</p>
|
|
||||||
<template id="filterTemplate">
|
|
||||||
<div class="quiet">
|
|
||||||
Filter:
|
|
||||||
<input type="search" id="fileSearch">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class='status-line high'></div>
|
|
||||||
<pre><table class="coverage">
|
|
||||||
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
||||||
<a name='L2'></a><a href='#L2'>2</a>
|
|
||||||
<a name='L3'></a><a href='#L3'>3</a>
|
|
||||||
<a name='L4'></a><a href='#L4'>4</a>
|
|
||||||
<a name='L5'></a><a href='#L5'>5</a>
|
|
||||||
<a name='L6'></a><a href='#L6'>6</a>
|
|
||||||
<a name='L7'></a><a href='#L7'>7</a>
|
|
||||||
<a name='L8'></a><a href='#L8'>8</a>
|
|
||||||
<a name='L9'></a><a href='#L9'>9</a>
|
|
||||||
<a name='L10'></a><a href='#L10'>10</a>
|
|
||||||
<a name='L11'></a><a href='#L11'>11</a>
|
|
||||||
<a name='L12'></a><a href='#L12'>12</a>
|
|
||||||
<a name='L13'></a><a href='#L13'>13</a>
|
|
||||||
<a name='L14'></a><a href='#L14'>14</a>
|
|
||||||
<a name='L15'></a><a href='#L15'>15</a>
|
|
||||||
<a name='L16'></a><a href='#L16'>16</a>
|
|
||||||
<a name='L17'></a><a href='#L17'>17</a>
|
|
||||||
<a name='L18'></a><a href='#L18'>18</a>
|
|
||||||
<a name='L19'></a><a href='#L19'>19</a>
|
|
||||||
<a name='L20'></a><a href='#L20'>20</a>
|
|
||||||
<a name='L21'></a><a href='#L21'>21</a>
|
|
||||||
<a name='L22'></a><a href='#L22'>22</a>
|
|
||||||
<a name='L23'></a><a href='#L23'>23</a>
|
|
||||||
<a name='L24'></a><a href='#L24'>24</a>
|
|
||||||
<a name='L25'></a><a href='#L25'>25</a>
|
|
||||||
<a name='L26'></a><a href='#L26'>26</a>
|
|
||||||
<a name='L27'></a><a href='#L27'>27</a>
|
|
||||||
<a name='L28'></a><a href='#L28'>28</a>
|
|
||||||
<a name='L29'></a><a href='#L29'>29</a>
|
|
||||||
<a name='L30'></a><a href='#L30'>30</a>
|
|
||||||
<a name='L31'></a><a href='#L31'>31</a>
|
|
||||||
<a name='L32'></a><a href='#L32'>32</a>
|
|
||||||
<a name='L33'></a><a href='#L33'>33</a>
|
|
||||||
<a name='L34'></a><a href='#L34'>34</a>
|
|
||||||
<a name='L35'></a><a href='#L35'>35</a>
|
|
||||||
<a name='L36'></a><a href='#L36'>36</a>
|
|
||||||
<a name='L37'></a><a href='#L37'>37</a>
|
|
||||||
<a name='L38'></a><a href='#L38'>38</a>
|
|
||||||
<a name='L39'></a><a href='#L39'>39</a>
|
|
||||||
<a name='L40'></a><a href='#L40'>40</a>
|
|
||||||
<a name='L41'></a><a href='#L41'>41</a>
|
|
||||||
<a name='L42'></a><a href='#L42'>42</a>
|
|
||||||
<a name='L43'></a><a href='#L43'>43</a>
|
|
||||||
<a name='L44'></a><a href='#L44'>44</a>
|
|
||||||
<a name='L45'></a><a href='#L45'>45</a>
|
|
||||||
<a name='L46'></a><a href='#L46'>46</a>
|
|
||||||
<a name='L47'></a><a href='#L47'>47</a>
|
|
||||||
<a name='L48'></a><a href='#L48'>48</a>
|
|
||||||
<a name='L49'></a><a href='#L49'>49</a>
|
|
||||||
<a name='L50'></a><a href='#L50'>50</a>
|
|
||||||
<a name='L51'></a><a href='#L51'>51</a>
|
|
||||||
<a name='L52'></a><a href='#L52'>52</a>
|
|
||||||
<a name='L53'></a><a href='#L53'>53</a>
|
|
||||||
<a name='L54'></a><a href='#L54'>54</a>
|
|
||||||
<a name='L55'></a><a href='#L55'>55</a>
|
|
||||||
<a name='L56'></a><a href='#L56'>56</a>
|
|
||||||
<a name='L57'></a><a href='#L57'>57</a>
|
|
||||||
<a name='L58'></a><a href='#L58'>58</a>
|
|
||||||
<a name='L59'></a><a href='#L59'>59</a>
|
|
||||||
<a name='L60'></a><a href='#L60'>60</a>
|
|
||||||
<a name='L61'></a><a href='#L61'>61</a>
|
|
||||||
<a name='L62'></a><a href='#L62'>62</a>
|
|
||||||
<a name='L63'></a><a href='#L63'>63</a>
|
|
||||||
<a name='L64'></a><a href='#L64'>64</a>
|
|
||||||
<a name='L65'></a><a href='#L65'>65</a>
|
|
||||||
<a name='L66'></a><a href='#L66'>66</a>
|
|
||||||
<a name='L67'></a><a href='#L67'>67</a>
|
|
||||||
<a name='L68'></a><a href='#L68'>68</a>
|
|
||||||
<a name='L69'></a><a href='#L69'>69</a>
|
|
||||||
<a name='L70'></a><a href='#L70'>70</a>
|
|
||||||
<a name='L71'></a><a href='#L71'>71</a>
|
|
||||||
<a name='L72'></a><a href='#L72'>72</a>
|
|
||||||
<a name='L73'></a><a href='#L73'>73</a>
|
|
||||||
<a name='L74'></a><a href='#L74'>74</a>
|
|
||||||
<a name='L75'></a><a href='#L75'>75</a>
|
|
||||||
<a name='L76'></a><a href='#L76'>76</a>
|
|
||||||
<a name='L77'></a><a href='#L77'>77</a>
|
|
||||||
<a name='L78'></a><a href='#L78'>78</a>
|
|
||||||
<a name='L79'></a><a href='#L79'>79</a>
|
|
||||||
<a name='L80'></a><a href='#L80'>80</a>
|
|
||||||
<a name='L81'></a><a href='#L81'>81</a>
|
|
||||||
<a name='L82'></a><a href='#L82'>82</a>
|
|
||||||
<a name='L83'></a><a href='#L83'>83</a>
|
|
||||||
<a name='L84'></a><a href='#L84'>84</a>
|
|
||||||
<a name='L85'></a><a href='#L85'>85</a>
|
|
||||||
<a name='L86'></a><a href='#L86'>86</a>
|
|
||||||
<a name='L87'></a><a href='#L87'>87</a>
|
|
||||||
<a name='L88'></a><a href='#L88'>88</a>
|
|
||||||
<a name='L89'></a><a href='#L89'>89</a>
|
|
||||||
<a name='L90'></a><a href='#L90'>90</a>
|
|
||||||
<a name='L91'></a><a href='#L91'>91</a>
|
|
||||||
<a name='L92'></a><a href='#L92'>92</a>
|
|
||||||
<a name='L93'></a><a href='#L93'>93</a>
|
|
||||||
<a name='L94'></a><a href='#L94'>94</a>
|
|
||||||
<a name='L95'></a><a href='#L95'>95</a>
|
|
||||||
<a name='L96'></a><a href='#L96'>96</a>
|
|
||||||
<a name='L97'></a><a href='#L97'>97</a>
|
|
||||||
<a name='L98'></a><a href='#L98'>98</a>
|
|
||||||
<a name='L99'></a><a href='#L99'>99</a>
|
|
||||||
<a name='L100'></a><a href='#L100'>100</a>
|
|
||||||
<a name='L101'></a><a href='#L101'>101</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-yes">2x</span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span>
|
|
||||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">export type Language = 'en' | 'cs';
|
|
||||||
|
|
||||||
export const t = {
|
|
||||||
en: {
|
|
||||||
sidebar: {
|
|
||||||
favorites: 'Favorites',
|
|
||||||
lakes: 'Lakes',
|
|
||||||
map: 'Map',
|
|
||||||
settings: 'Settings'
|
|
||||||
},
|
|
||||||
topbar: {
|
|
||||||
search: 'Search river or reservoir (e.g. Lipno)...',
|
|
||||||
updated: 'Last updated:'
|
|
||||||
},
|
|
||||||
kpi: {
|
|
||||||
level: 'WATER LEVEL',
|
|
||||||
flow: 'FLOW RATE',
|
|
||||||
inflow: 'Inflow',
|
|
||||||
outflow: 'Outflow',
|
|
||||||
fullness: 'STORAGE LEVEL',
|
|
||||||
volume: 'Volume'
|
|
||||||
},
|
|
||||||
chart: {
|
|
||||||
title: 'Long-term development',
|
|
||||||
timeframe: 'Timeframe',
|
|
||||||
timeframeMobile: 'Time',
|
|
||||||
view: 'View',
|
|
||||||
raw: 'Raw data',
|
|
||||||
smoothed: 'Smoothed',
|
|
||||||
calendar: 'Calendar',
|
|
||||||
all: 'All',
|
|
||||||
year: 'Year',
|
|
||||||
level: 'Water level',
|
|
||||||
inflow: 'Inflow',
|
|
||||||
outflow: 'Outflow',
|
|
||||||
maxLevel: 'Max retention level',
|
|
||||||
storageLevel: 'Storage space level',
|
|
||||||
dataSources: 'Data sources:',
|
|
||||||
createdIn: 'Created with ♥ in the Czech Republic'
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
title: 'Settings',
|
|
||||||
theme: 'Theme',
|
|
||||||
dark: 'Dark',
|
|
||||||
light: 'Light',
|
|
||||||
language: 'Language',
|
|
||||||
english: 'English',
|
|
||||||
czech: 'Čeština',
|
|
||||||
buyCoffee: 'Buy Me a Coffee'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cs: {
|
|
||||||
sidebar: {
|
|
||||||
favorites: 'Oblíbené',
|
|
||||||
lakes: 'Jezera',
|
|
||||||
map: 'Mapa',
|
|
||||||
settings: 'Nastavení'
|
|
||||||
},
|
|
||||||
topbar: {
|
|
||||||
search: 'Hledat tok nebo nádrž (např. Lipno)...',
|
|
||||||
updated: 'Aktualizováno:'
|
|
||||||
},
|
|
||||||
kpi: {
|
|
||||||
level: 'HLADINA',
|
|
||||||
flow: 'PRŮTOK',
|
|
||||||
inflow: 'Přítok',
|
|
||||||
outflow: 'Odtok',
|
|
||||||
fullness: 'ZÁSOBNÍ PROSTOR',
|
|
||||||
volume: 'Objem'
|
|
||||||
},
|
|
||||||
chart: {
|
|
||||||
title: 'Dlouhodobý vývoj',
|
|
||||||
timeframe: 'Časové období',
|
|
||||||
timeframeMobile: 'Časové',
|
|
||||||
view: 'Zobrazení',
|
|
||||||
raw: 'Syrová data',
|
|
||||||
smoothed: 'Vyhlazená',
|
|
||||||
calendar: 'Kalendář',
|
|
||||||
all: 'Vše',
|
|
||||||
year: 'Rok',
|
|
||||||
level: 'Hladina',
|
|
||||||
inflow: 'Přítok',
|
|
||||||
outflow: 'Odtok',
|
|
||||||
maxLevel: 'Max. retenční hladina',
|
|
||||||
storageLevel: 'Hladina zásobního prostoru',
|
|
||||||
dataSources: 'Zdroje dat:',
|
|
||||||
createdIn: 'Vytvořeno s ♥ v České republice'
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
title: 'Nastavení',
|
|
||||||
theme: 'Vzhled',
|
|
||||||
dark: 'Tmavý',
|
|
||||||
light: 'Světlý',
|
|
||||||
language: 'Jazyk',
|
|
||||||
english: 'English',
|
|
||||||
czech: 'Čeština',
|
|
||||||
buyCoffee: 'Kup mi kávu'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</pre></td></tr></table></pre>
|
|
||||||
|
|
||||||
<div class='push'></div><!-- for sticky footer -->
|
|
||||||
</div><!-- /wrapper -->
|
|
||||||
<div class='footer quiet pad2 space-top1 center small'>
|
|
||||||
Code coverage generated by
|
|
||||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
||||||
at 2026-06-05T21:03:50.324Z
|
|
||||||
</div>
|
|
||||||
<script src="../prettify.js"></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
prettyPrint();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="../sorter.js"></script>
|
|
||||||
<script src="../block-navigation.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
+22
-2
@@ -2,12 +2,32 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/jpeg" href="/favicon.jpg" />
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Davis Fencl</title>
|
<title>Hladinátor - Aktuální stav přehrad a nádrží</title>
|
||||||
|
<meta name="description" content="Sledujte aktuální vodní stav, průtok a vývoj počasí na českých přehradách a nádržích v reálném čase." />
|
||||||
|
<meta property="og:title" content="Hladinátor - Aktuální stav přehrad a nádrží" />
|
||||||
|
<meta property="og:description" content="Sledujte aktuální vodní stav, průtok a vývoj počasí na českých přehradách a nádržích v reálném čase." />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://hladinator.cz" />
|
||||||
|
<!-- PWA Settings -->
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<meta name="theme-color" content="#1e293b" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<link rel="apple-touch-icon" href="/favicon.png" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.tsx"></script>
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
navigator.serviceWorker.register('/sw.js')
|
||||||
|
.then(reg => console.log('Service Worker registered:', reg.scope))
|
||||||
|
.catch(err => console.error('Service Worker failed:', err));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Generated
+48
-1
@@ -14,6 +14,7 @@
|
|||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
"react-helmet-async": "^3.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-leaflet": "^5.0.0",
|
"react-leaflet": "^5.0.0",
|
||||||
"react-router-dom": "^7.9.6",
|
"react-router-dom": "^7.9.6",
|
||||||
@@ -3936,6 +3937,15 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/invariant": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -4016,7 +4026,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
@@ -4219,6 +4228,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"loose-envify": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
@@ -4688,6 +4709,26 @@
|
|||||||
"react": "^19.2.0"
|
"react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-fast-compare": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/react-helmet-async": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-nA3IEZfXiclgrz4KLxAhqJqIfFDuvzQwlKwpdmzZIuC1KNSghDEIXmyU0TKtbM+NafnkICcwx8CECFrZ/sL/1w==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"invariant": "^2.2.4",
|
||||||
|
"react-fast-compare": "^3.2.2",
|
||||||
|
"shallowequal": "^1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-icons": {
|
"node_modules/react-icons": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||||
@@ -4957,6 +4998,12 @@
|
|||||||
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
|
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/shallowequal": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"build-index": "tsx scripts/buildIndex.ts",
|
"build-index": "tsx scripts/buildIndex.ts",
|
||||||
"data:update": "npm run scrape && npm run build-index",
|
"data:update": "npm run scrape && npm run build-index",
|
||||||
"data:watch": "tsx scripts/watchData.ts",
|
"data:watch": "tsx scripts/watchData.ts",
|
||||||
|
"data:fix": "tsx scripts/fix_lake_inflows.ts",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
"test:watch": "vitest",
|
"test:watch": "vitest",
|
||||||
"coverage": "vitest run --coverage"
|
"coverage": "vitest run --coverage"
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
"react-helmet-async": "^3.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-leaflet": "^5.0.0",
|
"react-leaflet": "^5.0.0",
|
||||||
"react-router-dom": "^7.9.6",
|
"react-router-dom": "^7.9.6",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12638
File diff suppressed because it is too large
Load Diff
+15455
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15482
File diff suppressed because it is too large
Load Diff
+15248
File diff suppressed because it is too large
Load Diff
+12287
File diff suppressed because it is too large
Load Diff
+15500
File diff suppressed because it is too large
Load Diff
+15656
File diff suppressed because it is too large
Load Diff
+15167
File diff suppressed because it is too large
Load Diff
+12665
File diff suppressed because it is too large
Load Diff
+12665
File diff suppressed because it is too large
Load Diff
+15437
File diff suppressed because it is too large
Load Diff
+15545
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12982
-4000
File diff suppressed because it is too large
Load Diff
+13108
-4054
File diff suppressed because it is too large
Load Diff
+15473
File diff suppressed because it is too large
Load Diff
+15212
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+13943
File diff suppressed because it is too large
Load Diff
+15473
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15518
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15509
File diff suppressed because it is too large
Load Diff
+15446
File diff suppressed because it is too large
Load Diff
+15554
File diff suppressed because it is too large
Load Diff
+15257
File diff suppressed because it is too large
Load Diff
+15545
File diff suppressed because it is too large
Load Diff
+15563
File diff suppressed because it is too large
Load Diff
+15527
File diff suppressed because it is too large
Load Diff
+15509
File diff suppressed because it is too large
Load Diff
+15527
File diff suppressed because it is too large
Load Diff
+15545
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12912
-3993
File diff suppressed because it is too large
Load Diff
+15509
File diff suppressed because it is too large
Load Diff
+12947
-3992
File diff suppressed because it is too large
Load Diff
+13012
-4033
File diff suppressed because it is too large
Load Diff
+13002
-4038
File diff suppressed because it is too large
Load Diff
+13060
-4006
File diff suppressed because it is too large
Load Diff
+13015
-4015
File diff suppressed because it is too large
Load Diff
+13031
-4004
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15617
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"timestamp": "2026-05-31T05:00:00.000Z",
|
||||||
|
"level": 0,
|
||||||
|
"flow": 48.8,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-01T05:00:00.000Z",
|
||||||
|
"level": 34,
|
||||||
|
"flow": 80.2,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-02T05:00:00.000Z",
|
||||||
|
"level": 20,
|
||||||
|
"flow": 66.46,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-03T05:00:00.000Z",
|
||||||
|
"level": 18,
|
||||||
|
"flow": 63.7,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-04T05:00:00.000Z",
|
||||||
|
"level": 15,
|
||||||
|
"flow": 60.95,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-05T05:00:00.000Z",
|
||||||
|
"level": 15,
|
||||||
|
"flow": 61.4,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-05T20:00:00.000Z",
|
||||||
|
"level": 12,
|
||||||
|
"flow": 59.06,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-05T21:00:00.000Z",
|
||||||
|
"level": 7,
|
||||||
|
"flow": 54.32,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-05T22:00:00.000Z",
|
||||||
|
"level": 6,
|
||||||
|
"flow": 53.76,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-05T23:00:00.000Z",
|
||||||
|
"level": 11,
|
||||||
|
"flow": 57.64,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T00:00:00.000Z",
|
||||||
|
"level": 12,
|
||||||
|
"flow": 58.7,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T01:00:00.000Z",
|
||||||
|
"level": 12,
|
||||||
|
"flow": 58.25,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T02:00:00.000Z",
|
||||||
|
"level": 15,
|
||||||
|
"flow": 60.95,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T03:00:00.000Z",
|
||||||
|
"level": 13,
|
||||||
|
"flow": 59.87,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T04:00:00.000Z",
|
||||||
|
"level": 10,
|
||||||
|
"flow": 56.73,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T05:00:00.000Z",
|
||||||
|
"level": 15,
|
||||||
|
"flow": 61.76,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T06:00:00.000Z",
|
||||||
|
"level": 11,
|
||||||
|
"flow": 57.64,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T07:00:00.000Z",
|
||||||
|
"level": 6,
|
||||||
|
"flow": 53.6,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T08:00:00.000Z",
|
||||||
|
"level": 10,
|
||||||
|
"flow": 57.08,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T09:00:00.000Z",
|
||||||
|
"level": 14,
|
||||||
|
"flow": 60.68,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T10:00:00.000Z",
|
||||||
|
"level": 7,
|
||||||
|
"flow": 54.4,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T11:00:00.000Z",
|
||||||
|
"level": 3,
|
||||||
|
"flow": 51.34,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T12:00:00.000Z",
|
||||||
|
"level": 12,
|
||||||
|
"flow": 58.25,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T13:00:00.000Z",
|
||||||
|
"level": 13,
|
||||||
|
"flow": 59.33,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T14:00:00.000Z",
|
||||||
|
"level": 5,
|
||||||
|
"flow": 52.71,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T15:00:00.000Z",
|
||||||
|
"level": 10,
|
||||||
|
"flow": 56.64,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T16:00:00.000Z",
|
||||||
|
"level": 11,
|
||||||
|
"flow": 57.4,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T17:00:00.000Z",
|
||||||
|
"level": 9,
|
||||||
|
"flow": 55.7,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T18:00:00.000Z",
|
||||||
|
"level": 3,
|
||||||
|
"flow": 51.18,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T18:10:00.000Z",
|
||||||
|
"level": 4,
|
||||||
|
"flow": 51.58,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T18:20:00.000Z",
|
||||||
|
"level": 4,
|
||||||
|
"flow": 51.66,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T18:30:00.000Z",
|
||||||
|
"level": 5,
|
||||||
|
"flow": 52.44,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-06T18:40:00.000Z",
|
||||||
|
"level": 5,
|
||||||
|
"flow": 53.04,
|
||||||
|
"inflow": 0,
|
||||||
|
"volume": 0,
|
||||||
|
"temperature": 22.1,
|
||||||
|
"precipitation": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1 +0,0 @@
|
|||||||
[]
|
|
||||||
+15509
File diff suppressed because it is too large
Load Diff
+2016
-256
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 296 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 582 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"short_name": "Hladinátor",
|
||||||
|
"name": "Hladinátor - Stav přehrad a nádrží",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/favicon.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"purpose": "any maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "/",
|
||||||
|
"background_color": "#1e293b",
|
||||||
|
"theme_color": "#1e293b",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "portrait"
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
Sitemap: https://hladinator.cz/sitemap.xml
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
const CACHE_NAME = 'hladinator-v1';
|
||||||
|
const ASSETS_TO_CACHE = [
|
||||||
|
'/',
|
||||||
|
'/index.html',
|
||||||
|
'/favicon.png',
|
||||||
|
'/manifest.json'
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(CACHE_NAME).then((cache) => {
|
||||||
|
return cache.addAll(ASSETS_TO_CACHE);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
self.skipWaiting();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keys) => {
|
||||||
|
return Promise.all(
|
||||||
|
keys.map((key) => {
|
||||||
|
if (key !== CACHE_NAME) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
self.clients.claim();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
// Only handle same-origin HTTP/HTTPS requests
|
||||||
|
if (!event.request.url.startsWith(self.location.origin)) return;
|
||||||
|
|
||||||
|
event.respondWith(
|
||||||
|
caches.match(event.request).then((cachedResponse) => {
|
||||||
|
if (cachedResponse) {
|
||||||
|
// Fetch new version in background to update cache (stale-while-revalidate)
|
||||||
|
fetch(event.request).then((networkResponse) => {
|
||||||
|
if (networkResponse.status === 200) {
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, networkResponse));
|
||||||
|
}
|
||||||
|
}).catch(() => {/* ignore network failures */});
|
||||||
|
|
||||||
|
return cachedResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(event.request).then((networkResponse) => {
|
||||||
|
// Cache static files and JSON data on the fly
|
||||||
|
if (networkResponse.status === 200 && (
|
||||||
|
event.request.url.includes('.json') ||
|
||||||
|
event.request.url.includes('.css') ||
|
||||||
|
event.request.url.includes('.js')
|
||||||
|
)) {
|
||||||
|
const responseToCache = networkResponse.clone();
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, responseToCache));
|
||||||
|
}
|
||||||
|
return networkResponse;
|
||||||
|
}).catch(() => {
|
||||||
|
// Offline fallback
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
+1449
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user