From b54624be96ef220889c51ac65cf54ea05b725323 Mon Sep 17 00:00:00 2001 From: Alberto-Audrix Date: Tue, 8 Sep 2026 15:21:23 +0700 Subject: [PATCH] first commit --- .dockerignore | 25 + .env.example | 2 + .eslintrc.json | 42 + .gitignore | 12 + .prettierignore | 8 + .prettierrc | 9 + App.tsx | 36 + AppContent.tsx | 111 + README.md | 55 + backend/.env.example | 32 + backend/.gitignore | 10 + backend/README.md | 68 + backend/apps/.gitkeep | 0 backend/apps/__init__.py | 0 backend/apps/accounts/__init__.py | 0 backend/apps/accounts/apps.py | 8 + backend/apps/accounts/authentication.py | 32 + .../apps/accounts/migrations/0001_initial.py | 55 + .../migrations/0002_erd_named_primary_keys.py | 16 + .../accounts/migrations/0003_user_status.py | 39 + .../migrations/0004_sync_status_flags.py | 29 + .../migrations/0005_executive_roles.py | 45 + .../migrations/0006_user_managed_by.py | 26 + .../0007_user_managed_by_pending.py | 28 + .../0008_alter_managed_by_pending_buh_only.py | 25 + .../migrations/0009_account_admin_status.py | 30 + ...remove_is_staff_decouple_director_admin.py | 22 + .../migrations/0011_superuser_status.py | 39 + backend/apps/accounts/migrations/__init__.py | 0 backend/apps/accounts/models.py | 239 + backend/apps/accounts/permissions.py | 145 + backend/apps/accounts/scoping.py | 177 + backend/apps/accounts/serializers.py | 184 + backend/apps/accounts/tests_account_admin.py | 227 + backend/apps/accounts/tests_managed_by.py | 99 + backend/apps/accounts/tests_scoping.py | 118 + backend/apps/accounts/urls.py | 23 + backend/apps/accounts/views.py | 258 + backend/apps/farms/__init__.py | 0 backend/apps/farms/apps.py | 8 + backend/apps/farms/migrations/0001_initial.py | 91 + .../migrations/0002_cycle_requires_flock.py | 81 + .../migrations/0003_flock_cycle_nullable.py | 52 + .../0004_retarget_cycles_flock_fk.py | 59 + .../migrations/0005_erd_named_primary_keys.py | 16 + .../0006_erd_flock_belongs_to_cycle.py | 40 + .../0007_cycle_doc_in_weight_int.py | 16 + .../0008_cycle_feed_initial_balance.py | 16 + .../0009_flock_belongs_to_kandang.py | 50 + .../0010_restore_flock_cycle_erd.py | 32 + .../0011_flock_belongs_to_kandang.py | 45 + .../0012_cycle_feed_initial_balance_date.py | 15 + .../0013_kandang_feed_in_button_url.py | 15 + .../0014_kandang_feed_in_button_urls.py | 29 + .../migrations/0015_cycle_close_approval.py | 31 + .../0016_cycle_close_request_channel.py | 109 + .../farms/migrations/0017_site_city_site.py | 23 + backend/apps/farms/migrations/__init__.py | 0 backend/apps/farms/models.py | 276 + backend/apps/farms/serializers.py | 152 + backend/apps/farms/services/__init__.py | 0 backend/apps/farms/services/city_registry.py | 43 + backend/apps/farms/services/site_close.py | 49 + backend/apps/farms/tests.py | 394 + backend/apps/farms/tests_feed_in_button.py | 75 + backend/apps/farms/urls.py | 22 + backend/apps/farms/views.py | 382 + backend/apps/jobs/__init__.py | 0 backend/apps/jobs/apps.py | 8 + backend/apps/jobs/management/__init__.py | 0 .../apps/jobs/management/commands/__init__.py | 0 .../management/commands/advance_cycle_days.py | 11 + .../management/commands/bootstrap_admin.py | 117 + .../commands/recompute_kpi_rollups.py | 58 + .../jobs/management/commands/seed_demo.py | 146 + .../management/commands/seed_iot_10min.py | 239 + .../commands/seed_sukawarna_kandang4.py | 435 + .../commands/seed_sukawarna_kandang5.py | 293 + .../sync_chicken_counting_from_edge.py | 45 + .../management/commands/sync_iot_from_api.py | 23 + .../commands/sync_karung_from_web_admin.py | 29 + backend/apps/jobs/sukawarna_preview.py | 104 + backend/apps/jobs/tests.py | 55 + backend/apps/operations/__init__.py | 0 backend/apps/operations/apps.py | 8 + .../operations/migrations/0001_initial.py | 199 + .../migrations/0002_harvest_weight_float.py | 33 + .../migrations/0003_erd_named_primary_keys.py | 18 + .../migrations/0004_erd_column_updates.py | 25 + .../0005_erd_feed_and_doc_weight.py | 55 + .../migrations/0006_iotpanel_timestamp.py | 27 + .../0007_backfill_iotpanel_timestamp.py | 29 + .../0008_manualinput_feed_out_manual.py | 21 + .../migrations/0009_reportsnapshot.py | 61 + .../migrations/0010_delete_reportsnapshot.py | 14 + .../apps/operations/migrations/__init__.py | 0 backend/apps/operations/models.py | 170 + backend/apps/operations/serializers.py | 138 + backend/apps/operations/services/__init__.py | 0 .../services/chicken_counting_edge.py | 214 + .../apps/operations/services/feed_sacks.py | 71 + backend/apps/operations/services/iot_api.py | 264 + .../apps/operations/services/karung_web.py | 334 + .../apps/operations/services/manual_input.py | 38 + .../apps/operations/services/visibility.py | 29 + backend/apps/operations/tests.py | 441 + .../operations/tests_chicken_counting_edge.py | 213 + backend/apps/operations/tests_karung_web.py | 313 + backend/apps/operations/urls.py | 29 + backend/apps/operations/views.py | 256 + backend/apps/sync/__init__.py | 0 backend/apps/sync/apps.py | 8 + backend/apps/sync/management/__init__.py | 0 .../apps/sync/management/commands/__init__.py | 0 backend/apps/sync/migrations/0001_initial.py | 52 + .../migrations/0002_citysite_registered_by.py | 27 + backend/apps/sync/migrations/__init__.py | 0 backend/apps/sync/models.py | 47 + backend/apps/sync/serializers.py | 60 + backend/apps/sync/urls.py | 11 + backend/apps/sync/views.py | 77 + backend/config/__init__.py | 0 backend/config/asgi.py | 7 + backend/config/gunicorn.py | 6 + backend/config/settings.py | 211 + backend/config/urls.py | 20 + backend/config/wsgi.py | 7 + .../ERD_Dashboard_Chicken_Counting.md | 325 + backend/database/ERD_dashboard.png | Bin 0 -> 306998 bytes backend/database/erd_schema.sql | 315 + backend/dev.mjs | 56 + backend/manage.py | 19 + backend/package.json | 13 + backend/requirements.txt | 9 + components/AccountAdminShell.tsx | 51 + components/CobbStandardPage.tsx | 181 + components/CycleTimeline.tsx | 172 + components/Dashboard.tsx | 393 + components/EefDashboardPage.tsx | 471 + components/FcrDashboardPage.tsx | 473 + components/FeedSackCountingPage.tsx | 321 + components/Header.tsx | 217 + components/IotPanelPage.tsx | 595 + components/KandangRankingPage.tsx | 208 + components/KpiCard.tsx | 129 + components/PendingCloseQueue.tsx | 106 + components/SettingsPage.tsx | 557 + components/Sidebar.tsx | 151 + components/UserManagementPage.tsx | 362 + components/WeightMonitoringPage.tsx | 313 + components/WeightStandardPage.tsx | 62 + .../__tests__/AccountAdminShell.test.tsx | 32 + .../__tests__/FeedSackCountingPage.test.tsx | 288 + components/__tests__/SettingsPage.test.tsx | 216 + .../__tests__/UserManagementPage.test.tsx | 141 + components/auth/AuthPage.tsx | 22 + components/auth/LoginForm.tsx | 78 + components/common/ErrorBoundary.tsx | 55 + .../CountingAccuracyWarningBanner.tsx | 38 + components/counting/DataManagementPage.tsx | 850 + components/counting/PopulationTrendChart.tsx | 119 + .../CountingAccuracyWarningBanner.test.tsx | 36 + .../__tests__/DataManagementPage.test.tsx | 180 + components/dashboard/DashboardReportCtas.tsx | 43 + components/dashboard/KandangRankingTop5.tsx | 116 + components/dashboard/ReportPreviewOverlay.tsx | 639 + .../__tests__/DashboardReportCtas.test.tsx | 21 + components/feedSack/FeedDailySummaryTable.tsx | 265 + components/feedSack/FeedSaldoCard.tsx | 120 + components/feedSack/FeedStats.tsx | 145 + components/feedSack/FeedTrendChart.tsx | 108 + components/feedSack/InitialBalanceCard.tsx | 132 + .../feedSack/InitialBalanceComparison.tsx | 56 + .../iotPanel/IotPanelChillFactorCard.tsx | 131 + .../iotPanel/IotPanelExperienceTempCard.tsx | 97 + components/iotPanel/chillFactor.ts | 79 + components/sidebar/NavLink.tsx | 130 + components/ui/Feedback.tsx | 55 + components/weight/DailyDetailPanel.tsx | 103 + components/weight/DailyWeightGainChart.tsx | 193 + .../weight/DailyWeightProgressionChart.tsx | 157 + components/weight/WeightStats.tsx | 90 + context/AuthContext.tsx | 88 + context/FarmContext.tsx | 210 + index.html | 158 + index.tsx | 17 + mockData/cobbStandard.ts | 44 + mockData/weightStandardData.ts | 144 + package-lock.json | 8320 ++ package.json | 60 + public/favicon.png | Bin 0 -> 107806 bytes scripts/analyze_iot_api.py | 109 + scripts/analyze_iot_api_fast.py | 111 + scripts/experience_temperature.py | 175 + scripts/extract_iot_10min.py | 97 + scripts/extract_iot_cycle.py | 137 + scripts/extract_iot_cycle_fast.py | 139 + scripts/iot_panel_10min_extract.json | 74984 ++++++++++++++++ scripts/iot_panel_cycle_extract.json | 1105 + scripts/peek_xlsx.py | 13 + scripts/weigh_sample_count.py | 21 + services/__tests__/apiClient.test.ts | 75 + services/apiClient.ts | 271 + tests/setup.ts | 9 + tsconfig.json | 25 + types/api.ts | 324 + types/common.ts | 13 + types/dashboardReport.ts | 86 + utils/__tests__/buildInMemoryReport.test.ts | 180 + .../__tests__/countingAccuracyWarning.test.ts | 217 + utils/__tests__/kandangRanking.test.ts | 77 + utils/__tests__/reportSummary.test.ts | 220 + utils/__tests__/visibility.test.ts | 34 + utils/__tests__/weight.test.ts | 43 + utils/buildInMemoryReport.ts | 231 + utils/countingAccuracyWarning.ts | 96 + utils/format.ts | 74 + utils/kandangRanking.ts | 168 + utils/pdfExport.ts | 131 + utils/reportExcel.ts | 467 + utils/reportSummary.ts | 166 + utils/reportTotals.ts | 112 + utils/visibility.ts | 18 + utils/weight.ts | 107 + vite-env.d.ts | 9 + vite.config.ts | 30 + 226 files changed, 108840 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 App.tsx create mode 100644 AppContent.tsx create mode 100644 README.md create mode 100644 backend/.env.example create mode 100644 backend/.gitignore create mode 100644 backend/README.md create mode 100644 backend/apps/.gitkeep create mode 100644 backend/apps/__init__.py create mode 100644 backend/apps/accounts/__init__.py create mode 100644 backend/apps/accounts/apps.py create mode 100644 backend/apps/accounts/authentication.py create mode 100644 backend/apps/accounts/migrations/0001_initial.py create mode 100644 backend/apps/accounts/migrations/0002_erd_named_primary_keys.py create mode 100644 backend/apps/accounts/migrations/0003_user_status.py create mode 100644 backend/apps/accounts/migrations/0004_sync_status_flags.py create mode 100644 backend/apps/accounts/migrations/0005_executive_roles.py create mode 100644 backend/apps/accounts/migrations/0006_user_managed_by.py create mode 100644 backend/apps/accounts/migrations/0007_user_managed_by_pending.py create mode 100644 backend/apps/accounts/migrations/0008_alter_managed_by_pending_buh_only.py create mode 100644 backend/apps/accounts/migrations/0009_account_admin_status.py create mode 100644 backend/apps/accounts/migrations/0010_remove_is_staff_decouple_director_admin.py create mode 100644 backend/apps/accounts/migrations/0011_superuser_status.py create mode 100644 backend/apps/accounts/migrations/__init__.py create mode 100644 backend/apps/accounts/models.py create mode 100644 backend/apps/accounts/permissions.py create mode 100644 backend/apps/accounts/scoping.py create mode 100644 backend/apps/accounts/serializers.py create mode 100644 backend/apps/accounts/tests_account_admin.py create mode 100644 backend/apps/accounts/tests_managed_by.py create mode 100644 backend/apps/accounts/tests_scoping.py create mode 100644 backend/apps/accounts/urls.py create mode 100644 backend/apps/accounts/views.py create mode 100644 backend/apps/farms/__init__.py create mode 100644 backend/apps/farms/apps.py create mode 100644 backend/apps/farms/migrations/0001_initial.py create mode 100644 backend/apps/farms/migrations/0002_cycle_requires_flock.py create mode 100644 backend/apps/farms/migrations/0003_flock_cycle_nullable.py create mode 100644 backend/apps/farms/migrations/0004_retarget_cycles_flock_fk.py create mode 100644 backend/apps/farms/migrations/0005_erd_named_primary_keys.py create mode 100644 backend/apps/farms/migrations/0006_erd_flock_belongs_to_cycle.py create mode 100644 backend/apps/farms/migrations/0007_cycle_doc_in_weight_int.py create mode 100644 backend/apps/farms/migrations/0008_cycle_feed_initial_balance.py create mode 100644 backend/apps/farms/migrations/0009_flock_belongs_to_kandang.py create mode 100644 backend/apps/farms/migrations/0010_restore_flock_cycle_erd.py create mode 100644 backend/apps/farms/migrations/0011_flock_belongs_to_kandang.py create mode 100644 backend/apps/farms/migrations/0012_cycle_feed_initial_balance_date.py create mode 100644 backend/apps/farms/migrations/0013_kandang_feed_in_button_url.py create mode 100644 backend/apps/farms/migrations/0014_kandang_feed_in_button_urls.py create mode 100644 backend/apps/farms/migrations/0015_cycle_close_approval.py create mode 100644 backend/apps/farms/migrations/0016_cycle_close_request_channel.py create mode 100644 backend/apps/farms/migrations/0017_site_city_site.py create mode 100644 backend/apps/farms/migrations/__init__.py create mode 100644 backend/apps/farms/models.py create mode 100644 backend/apps/farms/serializers.py create mode 100644 backend/apps/farms/services/__init__.py create mode 100644 backend/apps/farms/services/city_registry.py create mode 100644 backend/apps/farms/services/site_close.py create mode 100644 backend/apps/farms/tests.py create mode 100644 backend/apps/farms/tests_feed_in_button.py create mode 100644 backend/apps/farms/urls.py create mode 100644 backend/apps/farms/views.py create mode 100644 backend/apps/jobs/__init__.py create mode 100644 backend/apps/jobs/apps.py create mode 100644 backend/apps/jobs/management/__init__.py create mode 100644 backend/apps/jobs/management/commands/__init__.py create mode 100644 backend/apps/jobs/management/commands/advance_cycle_days.py create mode 100644 backend/apps/jobs/management/commands/bootstrap_admin.py create mode 100644 backend/apps/jobs/management/commands/recompute_kpi_rollups.py create mode 100644 backend/apps/jobs/management/commands/seed_demo.py create mode 100644 backend/apps/jobs/management/commands/seed_iot_10min.py create mode 100644 backend/apps/jobs/management/commands/seed_sukawarna_kandang4.py create mode 100644 backend/apps/jobs/management/commands/seed_sukawarna_kandang5.py create mode 100644 backend/apps/jobs/management/commands/sync_chicken_counting_from_edge.py create mode 100644 backend/apps/jobs/management/commands/sync_iot_from_api.py create mode 100644 backend/apps/jobs/management/commands/sync_karung_from_web_admin.py create mode 100644 backend/apps/jobs/sukawarna_preview.py create mode 100644 backend/apps/jobs/tests.py create mode 100644 backend/apps/operations/__init__.py create mode 100644 backend/apps/operations/apps.py create mode 100644 backend/apps/operations/migrations/0001_initial.py create mode 100644 backend/apps/operations/migrations/0002_harvest_weight_float.py create mode 100644 backend/apps/operations/migrations/0003_erd_named_primary_keys.py create mode 100644 backend/apps/operations/migrations/0004_erd_column_updates.py create mode 100644 backend/apps/operations/migrations/0005_erd_feed_and_doc_weight.py create mode 100644 backend/apps/operations/migrations/0006_iotpanel_timestamp.py create mode 100644 backend/apps/operations/migrations/0007_backfill_iotpanel_timestamp.py create mode 100644 backend/apps/operations/migrations/0008_manualinput_feed_out_manual.py create mode 100644 backend/apps/operations/migrations/0009_reportsnapshot.py create mode 100644 backend/apps/operations/migrations/0010_delete_reportsnapshot.py create mode 100644 backend/apps/operations/migrations/__init__.py create mode 100644 backend/apps/operations/models.py create mode 100644 backend/apps/operations/serializers.py create mode 100644 backend/apps/operations/services/__init__.py create mode 100644 backend/apps/operations/services/chicken_counting_edge.py create mode 100644 backend/apps/operations/services/feed_sacks.py create mode 100644 backend/apps/operations/services/iot_api.py create mode 100644 backend/apps/operations/services/karung_web.py create mode 100644 backend/apps/operations/services/manual_input.py create mode 100644 backend/apps/operations/services/visibility.py create mode 100644 backend/apps/operations/tests.py create mode 100644 backend/apps/operations/tests_chicken_counting_edge.py create mode 100644 backend/apps/operations/tests_karung_web.py create mode 100644 backend/apps/operations/urls.py create mode 100644 backend/apps/operations/views.py create mode 100644 backend/apps/sync/__init__.py create mode 100644 backend/apps/sync/apps.py create mode 100644 backend/apps/sync/management/__init__.py create mode 100644 backend/apps/sync/management/commands/__init__.py create mode 100644 backend/apps/sync/migrations/0001_initial.py create mode 100644 backend/apps/sync/migrations/0002_citysite_registered_by.py create mode 100644 backend/apps/sync/migrations/__init__.py create mode 100644 backend/apps/sync/models.py create mode 100644 backend/apps/sync/serializers.py create mode 100644 backend/apps/sync/urls.py create mode 100644 backend/apps/sync/views.py create mode 100644 backend/config/__init__.py create mode 100644 backend/config/asgi.py create mode 100644 backend/config/gunicorn.py create mode 100644 backend/config/settings.py create mode 100644 backend/config/urls.py create mode 100644 backend/config/wsgi.py create mode 100644 backend/database/ERD_Dashboard_Chicken_Counting.md create mode 100644 backend/database/ERD_dashboard.png create mode 100644 backend/database/erd_schema.sql create mode 100644 backend/dev.mjs create mode 100644 backend/manage.py create mode 100644 backend/package.json create mode 100644 backend/requirements.txt create mode 100644 components/AccountAdminShell.tsx create mode 100644 components/CobbStandardPage.tsx create mode 100644 components/CycleTimeline.tsx create mode 100644 components/Dashboard.tsx create mode 100644 components/EefDashboardPage.tsx create mode 100644 components/FcrDashboardPage.tsx create mode 100644 components/FeedSackCountingPage.tsx create mode 100644 components/Header.tsx create mode 100644 components/IotPanelPage.tsx create mode 100644 components/KandangRankingPage.tsx create mode 100644 components/KpiCard.tsx create mode 100644 components/PendingCloseQueue.tsx create mode 100644 components/SettingsPage.tsx create mode 100644 components/Sidebar.tsx create mode 100644 components/UserManagementPage.tsx create mode 100644 components/WeightMonitoringPage.tsx create mode 100644 components/WeightStandardPage.tsx create mode 100644 components/__tests__/AccountAdminShell.test.tsx create mode 100644 components/__tests__/FeedSackCountingPage.test.tsx create mode 100644 components/__tests__/SettingsPage.test.tsx create mode 100644 components/__tests__/UserManagementPage.test.tsx create mode 100644 components/auth/AuthPage.tsx create mode 100644 components/auth/LoginForm.tsx create mode 100644 components/common/ErrorBoundary.tsx create mode 100644 components/counting/CountingAccuracyWarningBanner.tsx create mode 100644 components/counting/DataManagementPage.tsx create mode 100644 components/counting/PopulationTrendChart.tsx create mode 100644 components/counting/__tests__/CountingAccuracyWarningBanner.test.tsx create mode 100644 components/counting/__tests__/DataManagementPage.test.tsx create mode 100644 components/dashboard/DashboardReportCtas.tsx create mode 100644 components/dashboard/KandangRankingTop5.tsx create mode 100644 components/dashboard/ReportPreviewOverlay.tsx create mode 100644 components/dashboard/__tests__/DashboardReportCtas.test.tsx create mode 100644 components/feedSack/FeedDailySummaryTable.tsx create mode 100644 components/feedSack/FeedSaldoCard.tsx create mode 100644 components/feedSack/FeedStats.tsx create mode 100644 components/feedSack/FeedTrendChart.tsx create mode 100644 components/feedSack/InitialBalanceCard.tsx create mode 100644 components/feedSack/InitialBalanceComparison.tsx create mode 100644 components/iotPanel/IotPanelChillFactorCard.tsx create mode 100644 components/iotPanel/IotPanelExperienceTempCard.tsx create mode 100644 components/iotPanel/chillFactor.ts create mode 100644 components/sidebar/NavLink.tsx create mode 100644 components/ui/Feedback.tsx create mode 100644 components/weight/DailyDetailPanel.tsx create mode 100644 components/weight/DailyWeightGainChart.tsx create mode 100644 components/weight/DailyWeightProgressionChart.tsx create mode 100644 components/weight/WeightStats.tsx create mode 100644 context/AuthContext.tsx create mode 100644 context/FarmContext.tsx create mode 100644 index.html create mode 100644 index.tsx create mode 100644 mockData/cobbStandard.ts create mode 100644 mockData/weightStandardData.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon.png create mode 100644 scripts/analyze_iot_api.py create mode 100644 scripts/analyze_iot_api_fast.py create mode 100644 scripts/experience_temperature.py create mode 100644 scripts/extract_iot_10min.py create mode 100644 scripts/extract_iot_cycle.py create mode 100644 scripts/extract_iot_cycle_fast.py create mode 100644 scripts/iot_panel_10min_extract.json create mode 100644 scripts/iot_panel_cycle_extract.json create mode 100644 scripts/peek_xlsx.py create mode 100644 scripts/weigh_sample_count.py create mode 100644 services/__tests__/apiClient.test.ts create mode 100644 services/apiClient.ts create mode 100644 tests/setup.ts create mode 100644 tsconfig.json create mode 100644 types/api.ts create mode 100644 types/common.ts create mode 100644 types/dashboardReport.ts create mode 100644 utils/__tests__/buildInMemoryReport.test.ts create mode 100644 utils/__tests__/countingAccuracyWarning.test.ts create mode 100644 utils/__tests__/kandangRanking.test.ts create mode 100644 utils/__tests__/reportSummary.test.ts create mode 100644 utils/__tests__/visibility.test.ts create mode 100644 utils/__tests__/weight.test.ts create mode 100644 utils/buildInMemoryReport.ts create mode 100644 utils/countingAccuracyWarning.ts create mode 100644 utils/format.ts create mode 100644 utils/kandangRanking.ts create mode 100644 utils/pdfExport.ts create mode 100644 utils/reportExcel.ts create mode 100644 utils/reportSummary.ts create mode 100644 utils/reportTotals.ts create mode 100644 utils/visibility.ts create mode 100644 utils/weight.ts create mode 100644 vite-env.d.ts create mode 100644 vite.config.ts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..dd4c05a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +node_modules +npm-debug.log +.env +.env.local +.env.*.local +dist +dist-ssr +coverage +.vite +*.local +.git +.gitignore +docker-compose*.yml +DOCKER.md +README.md + +# Backend artifacts (api image copies backend/ explicitly) +backend/.venv +backend/venv +backend/__pycache__ +backend/db.sqlite3 +backend/data +backend/media +backend/staticfiles +backend/*.egg-info diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..18e030c --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# Local dev: Vite proxies /api → HQ Django :8001 +VITE_API_BASE=/api/v1 diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..169baf5 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "plugins": ["@typescript-eslint", "react", "react-hooks", "prettier"], + "rules": { + "prettier/prettier": "error", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_" + } + ], + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "react-hooks/exhaustive-deps": "warn", + "react-hooks/static-components": "off", + "react-hooks/purity": "off", + "react-hooks/set-state-in-effect": "off", + "react/no-unescaped-entities": "off" + }, + "settings": { + "react": { + "version": "detect" + } + }, + "ignorePatterns": ["dist", "node_modules", "*.config.js", "*.config.ts"] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9cc606 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +node_modules +dist +dist-ssr +*.local +.env +coverage +.vite +backup +__pycache__ +docker-compose.override.yml +docs/ +.superpowers/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..bbc1ea4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +node_modules +dist +dist-ssr +coverage +.vite +backend/.venv +backend/.pytest_cache +backend/**/node_modules diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7293ce1 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "printWidth": 100, + "trailingComma": "es5", + "arrowParens": "always", + "endOfLine": "lf" +} diff --git a/App.tsx b/App.tsx new file mode 100644 index 0000000..2932309 --- /dev/null +++ b/App.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import AppContent from './AppContent.tsx'; +import AccountAdminShell from './components/AccountAdminShell.tsx'; +import { AuthProvider, useAuth } from './context/AuthContext.tsx'; +import { FarmProvider } from './context/FarmContext.tsx'; +import AuthPage from './components/auth/AuthPage.tsx'; +import { Spinner } from './components/ui/Feedback.tsx'; + +const Gate: React.FC = () => { + const { user, loading } = useAuth(); + if (loading) { + return ( +
+ +
+ ); + } + if (!user) return ; + // Account Admin: User Management only. Superuser uses ops shell + Manajemen Akun nav. + if (user.status === 'account_admin') { + return ; + } + return ( + + + + ); +}; + +const App: React.FC = () => ( + + + +); + +export default App; diff --git a/AppContent.tsx b/AppContent.tsx new file mode 100644 index 0000000..2beafec --- /dev/null +++ b/AppContent.tsx @@ -0,0 +1,111 @@ +import React, { useState } from 'react'; +import type { View } from './types/common.ts'; +import { useFarm } from './context/FarmContext.tsx'; +import Sidebar from './components/Sidebar.tsx'; +import Header from './components/Header.tsx'; +import CycleTimeline from './components/CycleTimeline.tsx'; +import Dashboard from './components/Dashboard.tsx'; +import DataManagementPage from './components/counting/DataManagementPage.tsx'; +import WeightMonitoringPage from './components/WeightMonitoringPage.tsx'; +import WeightStandardPage from './components/WeightStandardPage.tsx'; +import FeedSackCountingPage from './components/FeedSackCountingPage.tsx'; +import CobbStandardPage from './components/CobbStandardPage.tsx'; +import IotPanelPage from './components/IotPanelPage.tsx'; +import FcrDashboardPage from './components/FcrDashboardPage.tsx'; +import EefDashboardPage from './components/EefDashboardPage.tsx'; +import KandangRankingPage from './components/KandangRankingPage.tsx'; +import SettingsPage from './components/SettingsPage.tsx'; +import UserManagementPage from './components/UserManagementPage.tsx'; +import { Banner } from './components/ui/Feedback.tsx'; + +const AppContent: React.FC = () => { + const { error, loading } = useFarm(); + const [view, setView] = useState('dashboard'); + const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); + const [isTimelineVisible, setIsTimelineVisible] = useState(false); + const goSettings = () => setView('kandangSettings'); + + const renderView = () => { + switch (view) { + case 'dashboard': + return ; + case 'dataManagement': + return ; + case 'weightMonitoring': + return ; + case 'weightStandard': + return ; + case 'feedSackCounting': + return ; + case 'cobbStandard': + return ; + case 'iotPanel': + return ; + case 'fcrDashboard': + return ; + case 'eefDashboard': + return ; + case 'kandangRanking': + return ; + case 'kandangSettings': + return ; + case 'userManagement': + return ; + default: + return ; + } + }; + + return ( +
+ setIsSidebarCollapsed((v) => !v)} + /> +
+
setIsSidebarCollapsed((v) => !v)} + isTimelineVisible={isTimelineVisible} + onToggleTimeline={() => setIsTimelineVisible((v) => !v)} + /> +
+ {isTimelineVisible && ( +
+ +
+ )} +
+ {error && ( +
+ {error} +
+ )} + {renderView()} +
+
+
+ {loading && ( +
+
+
+
+
+
+

Memuat Data...

+

Mohon tunggu sebentar

+
+
+ )} +
+ ); +}; + +export default AppContent; diff --git a/README.md b/README.md new file mode 100644 index 0000000..698eb02 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# dashboard-cpsp-executive + +Main-office executive dashboard. Same frontend look as site `dashboard-cpsp`, HQ mirror API in `backend/`. + +## Architecture + +```text +City A/B/C (API+DB) --API key sync--> HQ mirror API+DB --session--> Executive FE (:3002) +``` + +- **Roles** + - `director` / `director_admin`: view all sites (`director_admin` is **not** Django superuser) + - `buh` / `bu_admin`: view only GMs they manage (`managed_by`) and those GMs' sites + - `gm` / `gm_admin`: register city sites + sync; **only `gm`** approves cycle close + - `account_admin`: IT Central — User Management only; no ops dashboards + - `superuser`: break-glass (`bootstrap_admin` / seed `admin`) — director-level ops + Manajemen Akun; hidden from user lists + - `inactive`: locked out + - No `is_staff` +- **City registry:** `/api/v1/city-sites/` (GM / GM Admin) +- **Approve close:** `POST /api/v1/cycles/{id}/approve-close/` (GM only) + +## Ports + +| App | UI | API | +|-----|----|-----| +| Site `dashboard-cpsp` | `:3001` | `:8000` | +| HQ `dashboard-cpsp-executive` | `:3002` | `:8001` | + +## Setup + +**Backend** + +```bash +cd backend +python -m venv .venv +.venv\Scripts\activate +pip install -r requirements.txt +cp .env.example .env +python manage.py migrate +python manage.py seed_demo +npm run dev +``` + +**Frontend** + +```bash +cd .. +cp .env.example .env +npm install +npm run dev +``` + +Open [http://localhost:3002](http://localhost:3002). + +Seed accounts: `admin`/`admin123` (`superuser` break-glass: ops + Manajemen Akun), `director`/`director123`, `director_admin`/`directoradmin123`, `buh`/`buh123`, `bu_admin`/`buadmin123`, `gm`/`gm123`, `gm_admin`/`gmadmin123`, `account_admin`/`accountadmin123` (IT user management only). diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..6b21171 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,32 @@ +DEBUG=True +SECRET_KEY=change-me-in-production +ALLOWED_HOSTS=localhost,127.0.0.1,api +CSRF_TRUSTED_ORIGINS=http://localhost:8001,http://127.0.0.1:8001,http://localhost:3002,http://127.0.0.1:3002 +CORS_ALLOWED_ORIGINS=http://localhost:3002,http://127.0.0.1:3002 +CORS_ALLOW_CREDENTIALS=True + +# SQLite (local HQ mirror) +DB_ENGINE=django.db.backends.sqlite3 +DB_NAME=db.sqlite3 + +API_PAGE_SIZE=50 +SESSION_COOKIE_SECURE=False +CSRF_COOKIE_SECURE=False + +BOOTSTRAP_API_KEY= + +BOOTSTRAP_ADMIN_USER=admin +BOOTSTRAP_ADMIN_PASSWORD= + +# Optional second login (seeded as GM when using bootstrap_admin) +BOOTSTRAP_STAFF_USER= +BOOTSTRAP_STAFF_PASSWORD= + +# City-edge syncs off at HQ (mirror via city-sites instead) +KARUNG_WEB_ADMIN_SYNC_ENABLED=false +IOT_SYNC_ENABLED=false +CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED=false +CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED=false + +DASHBOARD_PUBLISH_HOUR=17 +DASHBOARD_PUBLISH_MINUTE=0 diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..2a31268 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,10 @@ +.venv/ +__pycache__/ +*.py[cod] +.env +db.sqlite3 +data/ +media/ +staticfiles/ +*.egg-info/ +.Python diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..0077386 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,68 @@ +# HQ backend — dashboard-cpsp-executive + +Main-office **mirror API** for the executive frontend. Domain shapes match site `dashboard-cpsp` so the copied UI can talk to `/api/v1/`. + +## Roles + +| Status | Capabilities | Data scope | +|--------|----------------|------------| +| `director`, `director_admin` | **View only** (director_admin may repair farm structure writes). Not Django superuser. | **All** sites / GMs | +| `buh`, `bu_admin` | **View only** | Rollup of managed GMs' registered city sites | +| `gm` | View + register city URLs + sync + **approve cycle close** | Own sites / city sites | +| `gm_admin` | Same as GM **except** no cycle-close approval | Own sites / city sites | +| `account_admin` | **User Management only** (create / deactivate / reset password). No ops dashboards. Temp passwords shared out-of-band. | Users list (all product users; never lists `superuser`). | +| `superuser` | Break-glass: **ops dashboards (director scope) + Manajemen Akun**. Not creatable via UI; hidden from user lists. | All sites / GMs | +| `inactive` | Locked out | — | + +`bootstrap_admin` / seed `admin` uses status `superuser`. This app does not use `is_staff`. + +GM↔BUH link: `User.managed_by` (confirmed). **Only `gm`** may request a **`buh`** (not `bu_admin` / `gm_admin`); **only that `buh`** may approve. +City registry ownership: `CitySite.registered_by`. +GM farm visibility follows the Pengaturan city-site list: only HQ `Site` rows linked to an active registered `CitySite` are shown (empty list ⇒ no sites). +BUH farm visibility is the union of those lists for **confirmed** managed GMs (read-only Pengaturan rollup; optional GM filter in the header). + +`POST /api/v1/cycles/{id}/approve-close/` — GM only. +`POST /api/v1/city-sites/` — GM / GM Admin. + +## City registry + +`GET/POST /api/v1/city-sites/` — register city dashboard APIs. +`POST /api/v1/city-sites/{id}/sync/` and `POST /api/v1/city-sites/sync-all/` — stubs (`501`) until mirror pull is built. + +## Setup + +```bash +cd backend +python -m venv .venv +# Windows: .venv\Scripts\activate +pip install -r requirements.txt +cp .env.example .env +python manage.py migrate +python manage.py seed_demo +npm run dev +# → http://127.0.0.1:8001 +``` + +Seed logins: + +| Username | Password | Role | +|----------|----------|------| +| `admin` | `admin123` | `superuser` (break-glass: ops + Manajemen Akun; hidden from user lists) | +| `director` | `director123` | `director` | +| `director_admin` | `directoradmin123` | `director_admin` (product; not superuser) | +| `buh` | `buh123` | `buh` | +| `bu_admin` | `buadmin123` | `bu_admin` | +| `gm` | `gm123` | `gm` (owns Sukawarna demo data; managed by `buh`) | +| `gm_admin` | `gmadmin123` | `gm_admin` (sites only; no BUH request) | +| `account_admin` | `accountadmin123` | `account_admin` (IT Central user management only) | + +Legacy `staff` login is removed by `seed_demo` (sites reassigned to `gm`). + +## Ports + +| Service | Port | +|---------|------| +| HQ API | `:8001` | +| Executive FE | `:3002` | +| Site API (other repo) | `:8000` | +| Site FE | `:3001` | diff --git a/backend/apps/.gitkeep b/backend/apps/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/__init__.py b/backend/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/accounts/__init__.py b/backend/apps/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/accounts/apps.py b/backend/apps/accounts/apps.py new file mode 100644 index 0000000..3ccdb8c --- /dev/null +++ b/backend/apps/accounts/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.accounts" + label = "accounts" + verbose_name = "Accounts" diff --git a/backend/apps/accounts/authentication.py b/backend/apps/accounts/authentication.py new file mode 100644 index 0000000..c64b9f4 --- /dev/null +++ b/backend/apps/accounts/authentication.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from django.utils.translation import gettext_lazy as _ +from rest_framework import authentication, exceptions + +from apps.accounts.models import ApiKey + + +class ApiKeyAuthentication(authentication.BaseAuthentication): + """Authenticate via X-API-Key header (hashed lookup).""" + + keyword = "X-API-Key" + + def authenticate(self, request): + raw_key = request.headers.get(self.keyword) or request.META.get("HTTP_X_API_KEY") + if not raw_key: + return None + if len(raw_key) < 8: + raise exceptions.AuthenticationFailed(_("Invalid API key")) + + prefix = raw_key[:8] + candidates = ApiKey.objects.select_related("user").filter( + prefix=prefix, is_active=True, user__is_active=True + ) + for api_key in candidates: + if api_key.verify(raw_key): + api_key.touch() + return (api_key.user, api_key) + raise exceptions.AuthenticationFailed(_("Invalid API key")) + + def authenticate_header(self, request): + return self.keyword diff --git a/backend/apps/accounts/migrations/0001_initial.py b/backend/apps/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..02c694a --- /dev/null +++ b/backend/apps/accounts/migrations/0001_initial.py @@ -0,0 +1,55 @@ +# Generated by Django 5.2.17 on 2026-08-10 08:31 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('user_name', models.CharField(max_length=30, unique=True)), + ('is_staff', models.BooleanField(default=False)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'db_table': 'user_access', + 'ordering': ['user_name'], + }, + ), + migrations.CreateModel( + name='ApiKey', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('prefix', models.CharField(db_index=True, max_length=12)), + ('key_hash', models.CharField(max_length=64)), + ('is_active', models.BooleanField(default=True)), + ('last_used_at', models.DateTimeField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='api_keys', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'api_keys', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/backend/apps/accounts/migrations/0002_erd_named_primary_keys.py b/backend/apps/accounts/migrations/0002_erd_named_primary_keys.py new file mode 100644 index 0000000..9ff24cb --- /dev/null +++ b/backend/apps/accounts/migrations/0002_erd_named_primary_keys.py @@ -0,0 +1,16 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0001_initial"), + ] + + operations = [ + migrations.RenameField( + model_name="user", + old_name="id", + new_name="user_id", + ), + ] diff --git a/backend/apps/accounts/migrations/0003_user_status.py b/backend/apps/accounts/migrations/0003_user_status.py new file mode 100644 index 0000000..6f8cb78 --- /dev/null +++ b/backend/apps/accounts/migrations/0003_user_status.py @@ -0,0 +1,39 @@ +from django.db import migrations, models + + +def backfill_user_status(apps, schema_editor): + User = apps.get_model("accounts", "User") + for user in User.objects.all(): + if user.is_superuser: + status = "superadmin" + flags = {"is_active": True, "is_staff": True, "is_superuser": True} + elif not user.is_active: + status = "inactive" + flags = {"is_active": False, "is_staff": False, "is_superuser": False} + else: + status = "active" + flags = {"is_active": True, "is_staff": False, "is_superuser": False} + User.objects.filter(pk=user.pk).update(status=status, **flags) + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0002_erd_named_primary_keys"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="status", + field=models.CharField( + choices=[ + ("active", "Active"), + ("inactive", "Inactive"), + ("superadmin", "Super Admin"), + ], + default="active", + max_length=30, + ), + ), + migrations.RunPython(backfill_user_status, migrations.RunPython.noop), + ] diff --git a/backend/apps/accounts/migrations/0004_sync_status_flags.py b/backend/apps/accounts/migrations/0004_sync_status_flags.py new file mode 100644 index 0000000..b8130bb --- /dev/null +++ b/backend/apps/accounts/migrations/0004_sync_status_flags.py @@ -0,0 +1,29 @@ +from django.db import migrations + + +def sync_status_flags(apps, schema_editor): + User = apps.get_model("accounts", "User") + for user in User.objects.all(): + if user.status == "inactive": + user.is_active = False + user.is_staff = False + user.is_superuser = False + elif user.status == "superadmin": + user.is_active = True + user.is_staff = False + user.is_superuser = True + else: + user.is_active = True + user.is_superuser = False + user.save(update_fields=["is_active", "is_staff", "is_superuser", "updated_at"]) + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0003_user_status"), + ] + + operations = [ + migrations.RunPython(sync_status_flags, migrations.RunPython.noop), + ] \ No newline at end of file diff --git a/backend/apps/accounts/migrations/0005_executive_roles.py b/backend/apps/accounts/migrations/0005_executive_roles.py new file mode 100644 index 0000000..f2a257e --- /dev/null +++ b/backend/apps/accounts/migrations/0005_executive_roles.py @@ -0,0 +1,45 @@ +from django.db import migrations, models + + +def migrate_legacy_statuses(apps, schema_editor): + User = apps.get_model("accounts", "User") + for user in User.objects.all(): + if user.status == "superadmin": + new_status = "director_admin" + flags = {"is_active": True, "is_staff": True, "is_superuser": True} + elif user.status == "active": + new_status = "gm" + flags = {"is_active": True, "is_staff": False, "is_superuser": False} + elif user.status == "inactive": + new_status = "inactive" + flags = {"is_active": False, "is_staff": False, "is_superuser": False} + else: + continue + User.objects.filter(pk=user.pk).update(status=new_status, **flags) + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0004_sync_status_flags"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="status", + field=models.CharField( + choices=[ + ("inactive", "Inactive"), + ("gm", "GM"), + ("gm_admin", "GM Admin"), + ("buh", "BUH"), + ("bu_admin", "BU Admin"), + ("director", "Director"), + ("director_admin", "Director Admin"), + ], + default="gm", + max_length=30, + ), + ), + migrations.RunPython(migrate_legacy_statuses, migrations.RunPython.noop), + ] diff --git a/backend/apps/accounts/migrations/0006_user_managed_by.py b/backend/apps/accounts/migrations/0006_user_managed_by.py new file mode 100644 index 0000000..659f024 --- /dev/null +++ b/backend/apps/accounts/migrations/0006_user_managed_by.py @@ -0,0 +1,26 @@ +# Generated for HQ visibility scoping + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0005_executive_roles"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="managed_by", + field=models.ForeignKey( + blank=True, + limit_choices_to={"status__in": ("buh", "bu_admin")}, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="managed_gms", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/backend/apps/accounts/migrations/0007_user_managed_by_pending.py b/backend/apps/accounts/migrations/0007_user_managed_by_pending.py new file mode 100644 index 0000000..fa55a32 --- /dev/null +++ b/backend/apps/accounts/migrations/0007_user_managed_by_pending.py @@ -0,0 +1,28 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0006_user_managed_by"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="managed_by_pending", + field=models.ForeignKey( + blank=True, + limit_choices_to={"status__in": ("buh", "bu_admin")}, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="pending_managed_gms", + to="accounts.user", + ), + ), + migrations.AddField( + model_name="user", + name="managed_by_requested_at", + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/backend/apps/accounts/migrations/0008_alter_managed_by_pending_buh_only.py b/backend/apps/accounts/migrations/0008_alter_managed_by_pending_buh_only.py new file mode 100644 index 0000000..9cd7825 --- /dev/null +++ b/backend/apps/accounts/migrations/0008_alter_managed_by_pending_buh_only.py @@ -0,0 +1,25 @@ +# Generated manually for managed_by_pending BUH-only limit + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0007_user_managed_by_pending"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="managed_by_pending", + field=models.ForeignKey( + blank=True, + limit_choices_to={"status": "buh"}, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="pending_managed_gms", + to="accounts.user", + ), + ), + ] diff --git a/backend/apps/accounts/migrations/0009_account_admin_status.py b/backend/apps/accounts/migrations/0009_account_admin_status.py new file mode 100644 index 0000000..c12cce1 --- /dev/null +++ b/backend/apps/accounts/migrations/0009_account_admin_status.py @@ -0,0 +1,30 @@ +# Generated manually for account_admin status + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0008_alter_managed_by_pending_buh_only"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="status", + field=models.CharField( + choices=[ + ("inactive", "Inactive"), + ("gm", "GM"), + ("gm_admin", "GM Admin"), + ("buh", "BUH"), + ("bu_admin", "BU Admin"), + ("director", "Director"), + ("director_admin", "Director Admin"), + ("account_admin", "Account Admin"), + ], + default="gm", + max_length=30, + ), + ), + ] diff --git a/backend/apps/accounts/migrations/0010_remove_is_staff_decouple_director_admin.py b/backend/apps/accounts/migrations/0010_remove_is_staff_decouple_director_admin.py new file mode 100644 index 0000000..4a63d42 --- /dev/null +++ b/backend/apps/accounts/migrations/0010_remove_is_staff_decouple_director_admin.py @@ -0,0 +1,22 @@ +from django.db import migrations + + +def strip_director_admin_superuser(apps, schema_editor): + User = apps.get_model("accounts", "User") + User.objects.filter(status="director_admin", is_superuser=True).update( + is_superuser=False + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0009_account_admin_status"), + ] + + operations = [ + migrations.RunPython(strip_director_admin_superuser, migrations.RunPython.noop), + migrations.RemoveField( + model_name="user", + name="is_staff", + ), + ] diff --git a/backend/apps/accounts/migrations/0011_superuser_status.py b/backend/apps/accounts/migrations/0011_superuser_status.py new file mode 100644 index 0000000..fe97c73 --- /dev/null +++ b/backend/apps/accounts/migrations/0011_superuser_status.py @@ -0,0 +1,39 @@ +from django.db import migrations, models + + +def migrate_break_glass_to_superuser_status(apps, schema_editor): + User = apps.get_model("accounts", "User") + User.objects.filter(is_superuser=True).exclude(status="inactive").update( + status="superuser" + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0010_remove_is_staff_decouple_director_admin"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="status", + field=models.CharField( + choices=[ + ("inactive", "Inactive"), + ("gm", "GM"), + ("gm_admin", "GM Admin"), + ("buh", "BUH"), + ("bu_admin", "BU Admin"), + ("director", "Director"), + ("director_admin", "Director Admin"), + ("account_admin", "Account Admin"), + ("superuser", "Superuser"), + ], + default="gm", + max_length=30, + ), + ), + migrations.RunPython( + migrate_break_glass_to_superuser_status, migrations.RunPython.noop + ), + ] diff --git a/backend/apps/accounts/migrations/__init__.py b/backend/apps/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/accounts/models.py b/backend/apps/accounts/models.py new file mode 100644 index 0000000..f459897 --- /dev/null +++ b/backend/apps/accounts/models.py @@ -0,0 +1,239 @@ +from __future__ import annotations + +import hashlib +import secrets + +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin +from django.db import models +from django.utils import timezone + + +class UserManager(BaseUserManager): + def create_user(self, user_name: str, password: str | None = None, **extra_fields): + if not user_name: + raise ValueError("user_name is required") + extra_fields.setdefault("status", User.STATUS_GM) + extra_fields.setdefault("is_superuser", False) + user = self.model(user_name=user_name, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, user_name: str, password: str | None = None, **extra_fields): + """Break-glass: status=superuser (ops + user management). Hidden from user lists.""" + extra_fields["status"] = User.STATUS_SUPERUSER + extra_fields["is_superuser"] = True + return self.create_user(user_name, password, **extra_fields) + + +class User(AbstractBaseUser, PermissionsMixin): + """HQ executive user. Roles are distinct from site dashboard active/superadmin.""" + + STATUS_INACTIVE = "inactive" + STATUS_GM = "gm" + STATUS_GM_ADMIN = "gm_admin" + STATUS_BUH = "buh" + STATUS_BU_ADMIN = "bu_admin" + STATUS_DIRECTOR = "director" + STATUS_DIRECTOR_ADMIN = "director_admin" + STATUS_ACCOUNT_ADMIN = "account_admin" + STATUS_SUPERUSER = "superuser" + + STATUS_CHOICES = [ + (STATUS_INACTIVE, "Inactive"), + (STATUS_GM, "GM"), + (STATUS_GM_ADMIN, "GM Admin"), + (STATUS_BUH, "BUH"), + (STATUS_BU_ADMIN, "BU Admin"), + (STATUS_DIRECTOR, "Director"), + (STATUS_DIRECTOR_ADMIN, "Director Admin"), + (STATUS_ACCOUNT_ADMIN, "Account Admin"), + (STATUS_SUPERUSER, "Superuser"), + ] + + # Roles that may sign in and use the executive dashboard. + EXECUTIVE_STATUSES = frozenset( + { + STATUS_GM, + STATUS_GM_ADMIN, + STATUS_BUH, + STATUS_BU_ADMIN, + STATUS_DIRECTOR, + STATUS_DIRECTOR_ADMIN, + STATUS_ACCOUNT_ADMIN, + STATUS_SUPERUSER, + } + ) + + # BU / Director "*_admin" are view-only (same as buh / director). + # Kept for labeling only — no extra write powers. + ADMIN_STATUSES = frozenset( + { + STATUS_BU_ADMIN, + STATUS_DIRECTOR_ADMIN, + } + ) + + user_id = models.BigAutoField(primary_key=True) + user_name = models.CharField(max_length=30, unique=True) + status = models.CharField(max_length=30, choices=STATUS_CHOICES, default=STATUS_GM) + # BUH who manages this GM / GM Admin (unused for director / buh themselves). + managed_by = models.ForeignKey( + "self", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="managed_gms", + limit_choices_to={"status__in": ("buh", "bu_admin")}, + ) + # GM-requested BUH waiting for confirmation (BUH only — not BU Admin). + managed_by_pending = models.ForeignKey( + "self", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="pending_managed_gms", + limit_choices_to={"status": "buh"}, + ) + managed_by_requested_at = models.DateTimeField(null=True, blank=True) + is_active = models.BooleanField(default=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + objects = UserManager() + + USERNAME_FIELD = "user_name" + REQUIRED_FIELDS: list[str] = [] + + class Meta: + db_table = "user_access" + ordering = ["user_name"] + + def __str__(self) -> str: + return self.user_name + + @property + def is_executive(self) -> bool: + return self.status in self.EXECUTIVE_STATUSES + + @property + def is_executive_admin(self) -> bool: + return self.status in self.ADMIN_STATUSES + + def request_managed_by(self, buh: "User") -> None: + """GM asks to report under a BUH (pending until that BUH confirms).""" + from django.core.exceptions import ValidationError + + if self.status != self.STATUS_GM: + raise ValidationError("Only GM can request a BUH.") + if buh.status != self.STATUS_BUH: + raise ValidationError("Target must be a BUH (not BU Admin).") + if self.managed_by_id == buh.pk and self.managed_by_pending_id is None: + raise ValidationError("Already managed by this BUH.") + self.managed_by_pending = buh + self.managed_by_requested_at = timezone.now() + self.save( + update_fields=["managed_by_pending", "managed_by_requested_at", "updated_at"] + ) + + def cancel_managed_by_request(self) -> None: + if self.managed_by_pending_id is None: + return + self.managed_by_pending = None + self.managed_by_requested_at = None + self.save( + update_fields=["managed_by_pending", "managed_by_requested_at", "updated_at"] + ) + + def approve_managed_by(self, approver: "User") -> None: + from django.core.exceptions import ValidationError + + if self.managed_by_pending_id is None: + raise ValidationError("No pending BUH request.") + if approver.pk != self.managed_by_pending_id: + raise ValidationError("Only the requested BUH can approve this request.") + if approver.status != self.STATUS_BUH: + raise ValidationError("Only a BUH (not BU Admin) can approve this request.") + self.managed_by = self.managed_by_pending + self.managed_by_pending = None + self.managed_by_requested_at = None + self.save( + update_fields=[ + "managed_by", + "managed_by_pending", + "managed_by_requested_at", + "updated_at", + ] + ) + + def reject_managed_by(self, approver: "User") -> None: + from django.core.exceptions import ValidationError + + if self.managed_by_pending_id is None: + raise ValidationError("No pending BUH request.") + if approver.pk != self.managed_by_pending_id: + raise ValidationError("Only the requested BUH can reject this request.") + if approver.status != self.STATUS_BUH: + raise ValidationError("Only a BUH (not BU Admin) can reject this request.") + self.managed_by_pending = None + self.managed_by_requested_at = None + self.save( + update_fields=["managed_by_pending", "managed_by_requested_at", "updated_at"] + ) + + def save(self, *args, **kwargs): + # Product roles never use Django is_staff. status=superuser is break-glass + # (ops + user management) and always carries is_superuser. + if self.status == self.STATUS_INACTIVE: + self.is_active = False + self.is_superuser = False + elif self.status == self.STATUS_SUPERUSER: + self.is_active = True + self.is_superuser = True + else: + self.is_active = True + self.is_superuser = False + super().save(*args, **kwargs) + + +class ApiKey(models.Model): + """Hashed API keys for X-API-Key authentication (inbound to HQ API).""" + + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="api_keys") + name = models.CharField(max_length=100) + prefix = models.CharField(max_length=12, db_index=True) + key_hash = models.CharField(max_length=64) + is_active = models.BooleanField(default=True) + last_used_at = models.DateTimeField(null=True, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "api_keys" + ordering = ["-created_at"] + + def __str__(self) -> str: + return f"{self.name} ({self.prefix}…)" + + @staticmethod + def hash_key(raw_key: str) -> str: + return hashlib.sha256(raw_key.encode("utf-8")).hexdigest() + + @classmethod + def generate(cls, user: User, name: str) -> tuple[ApiKey, str]: + raw = secrets.token_urlsafe(32) + prefix = raw[:8] + instance = cls.objects.create( + user=user, + name=name, + prefix=prefix, + key_hash=cls.hash_key(raw), + ) + return instance, raw + + def verify(self, raw_key: str) -> bool: + return secrets.compare_digest(self.key_hash, self.hash_key(raw_key)) + + def touch(self) -> None: + self.last_used_at = timezone.now() + self.save(update_fields=["last_used_at", "updated_at"]) diff --git a/backend/apps/accounts/permissions.py b/backend/apps/accounts/permissions.py new file mode 100644 index 0000000..863e040 --- /dev/null +++ b/backend/apps/accounts/permissions.py @@ -0,0 +1,145 @@ +"""HQ executive role helpers and DRF permission classes. + +Settled matrix (v1): +- buh, director (+ their admins until specified otherwise): view only +- gm + gm_admin: view + register city sites (URL) + sync from cities +- gm only (not gm_admin): approve cycle close +""" + +from __future__ import annotations + +from rest_framework import permissions + +from apps.accounts.models import User + +# View-only executives (no site registry, sync, or approvals). +VIEW_ONLY_STATUSES = frozenset( + { + User.STATUS_BUH, + User.STATUS_BU_ADMIN, + User.STATUS_DIRECTOR, + User.STATUS_DIRECTOR_ADMIN, + } +) + +# Can register city dashboard URLs into the HQ mirror registry. +SITE_REGISTRY_STATUSES = frozenset( + { + User.STATUS_GM, + User.STATUS_GM_ADMIN, + } +) + +# Can trigger city → HQ mirror sync. +SYNC_STATUSES = frozenset( + { + User.STATUS_GM, + User.STATUS_GM_ADMIN, + } +) + +# Cycle close approval — GM only (explicitly not gm_admin). +CYCLE_CLOSE_APPROVER_STATUSES = frozenset( + { + User.STATUS_GM, + } +) + +# Product user-management role (IT Central). Django superuser remains break-glass. +USER_ADMIN_STATUSES = frozenset( + { + User.STATUS_ACCOUNT_ADMIN, + } +) + + +def _status(user) -> str | None: + return getattr(user, "status", None) if user else None + + +def executive_user(user) -> bool: + return bool( + user + and getattr(user, "is_authenticated", False) + and _status(user) in User.EXECUTIVE_STATUSES + ) + + +def can_sync(user) -> bool: + return bool( + user + and getattr(user, "is_authenticated", False) + and _status(user) in SYNC_STATUSES + ) + + +def can_register_city_site(user) -> bool: + """GM / GM Admin may add city dashboard URLs to the HQ registry.""" + return bool( + user + and getattr(user, "is_authenticated", False) + and _status(user) in SITE_REGISTRY_STATUSES + ) + + +def can_approve_cycle_close(user) -> bool: + """Only GM (not gm_admin) may approve closing a cycle.""" + return bool( + user + and getattr(user, "is_authenticated", False) + and _status(user) in CYCLE_CLOSE_APPROVER_STATUSES + ) + + +def can_write_operations(user) -> bool: + """No manual ops create/edit/delete for executive roles.""" + return False + + +def can_manage_users(user) -> bool: + """Account Admin (IT Central) or Django superuser break-glass.""" + if not user or not getattr(user, "is_authenticated", False): + return False + if getattr(user, "is_superuser", False): + return True + return _status(user) in USER_ADMIN_STATUSES + + +def can_manage_city_registry(user) -> bool: + """Alias used by city-site write endpoints — same as register permission.""" + return can_register_city_site(user) or bool(getattr(user, "is_superuser", False)) + + +class IsExecutive(permissions.BasePermission): + def has_permission(self, request, view): + return executive_user(request.user) + + +class IsExecutiveAdmin(permissions.BasePermission): + def has_permission(self, request, view): + return can_manage_users(request.user) + + +class CanRegisterCitySite(permissions.BasePermission): + def has_permission(self, request, view): + return can_register_city_site(request.user) or bool( + getattr(request.user, "is_superuser", False) + ) + + +class CanApproveCycleClose(permissions.BasePermission): + def has_permission(self, request, view): + return can_approve_cycle_close(request.user) + + +class ReadOrSyncOnly(permissions.BasePermission): + """Safe methods for all executives; sync actions for GM / GM Admin only.""" + + def has_permission(self, request, view): + if not executive_user(request.user): + return False + if request.method in permissions.SAFE_METHODS: + return True + if getattr(view, "executive_sync_action", False): + return can_sync(request.user) + return can_write_operations(request.user) diff --git a/backend/apps/accounts/scoping.py b/backend/apps/accounts/scoping.py new file mode 100644 index 0000000..f116878 --- /dev/null +++ b/backend/apps/accounts/scoping.py @@ -0,0 +1,177 @@ +"""Visibility scoping for HQ executives. + +- director / director_admin: all sites / city sites / GMs +- buh / bu_admin: only GMs (and gm_admins) they manage, plus those GMs' sites +- gm / gm_admin: only their own sites / city sites they registered + +Farm Site rows are only visible to non-directors when linked to an active +CitySite in the viewer's Pengaturan registry. +""" + +from __future__ import annotations + +from django.db.models import QuerySet + +from apps.accounts.models import User + +DIRECTOR_STATUSES = frozenset( + { + User.STATUS_DIRECTOR, + User.STATUS_DIRECTOR_ADMIN, + User.STATUS_SUPERUSER, + } +) + +BUH_STATUSES = frozenset( + { + User.STATUS_BUH, + User.STATUS_BU_ADMIN, + } +) + +GM_STATUSES = frozenset( + { + User.STATUS_GM, + User.STATUS_GM_ADMIN, + } +) + + +def is_director_scope(user: User) -> bool: + return bool(user and user.status in DIRECTOR_STATUSES) + + +def is_buh_scope(user: User) -> bool: + return bool(user and user.status in BUH_STATUSES) + + +def is_gm_scope(user: User) -> bool: + return bool(user and user.status in GM_STATUSES) + + +def managed_gm_ids(buh: User) -> list[int]: + """User pks for GMs / GM Admins reporting to this BUH.""" + return list( + User.objects.filter( + managed_by=buh, + status__in=GM_STATUSES, + ).values_list("pk", flat=True) + ) + + +def visible_owner_ids(user: User) -> list[int] | None: + """ + Site.user / CitySite.registered_by ids this viewer may see. + + Returns None when there is no restriction (director / superuser). + """ + if is_director_scope(user): + return None + if is_buh_scope(user): + return managed_gm_ids(user) + if is_gm_scope(user): + return [user.pk] + return [] + + +def visible_active_city_site_ids(user: User) -> list[int] | None: + """ + Active CitySite pks in this viewer's Pengaturan registry. + + Returns None for directors (no restriction). Empty list means no farm sites. + """ + from apps.sync.models import CitySite + + owners = visible_owner_ids(user) + if owners is None: + return None + if not owners: + return [] + return list( + CitySite.objects.filter( + registered_by_id__in=owners, + is_active=True, + ).values_list("pk", flat=True) + ) + + +def is_account_admin_scope(user: User) -> bool: + return bool(user and user.status == User.STATUS_ACCOUNT_ADMIN) + + +def filter_users_queryset(qs: QuerySet, viewer: User) -> QuerySet: + """BUH sees managed GMs; director / account_admin see product users. + + Break-glass status=superuser is never listed in the user directory. + """ + qs = qs.exclude(status=User.STATUS_SUPERUSER) + if is_director_scope(viewer) or is_account_admin_scope(viewer): + return qs + if is_buh_scope(viewer): + return qs.filter(pk__in=managed_gm_ids(viewer)) + if is_gm_scope(viewer): + return qs.filter(pk=viewer.pk) + return qs.none() + + +def filter_sites_queryset(qs: QuerySet, viewer: User) -> QuerySet: + owners = visible_owner_ids(viewer) + if owners is None: + return qs + if not owners: + return qs.none() + city_ids = visible_active_city_site_ids(viewer) + if not city_ids: + return qs.none() + return qs.filter(user_id__in=owners, city_site_id__in=city_ids) + + +def filter_city_sites_queryset(qs: QuerySet, viewer: User) -> QuerySet: + owners = visible_owner_ids(viewer) + if owners is None: + return qs + if not owners: + return qs.none() + return qs.filter(registered_by_id__in=owners) + + +def filter_kandangs_queryset(qs: QuerySet, viewer: User) -> QuerySet: + owners = visible_owner_ids(viewer) + if owners is None: + return qs + if not owners: + return qs.none() + city_ids = visible_active_city_site_ids(viewer) + if not city_ids: + return qs.none() + return qs.filter(site__user_id__in=owners, site__city_site_id__in=city_ids) + + +def filter_flocks_queryset(qs: QuerySet, viewer: User) -> QuerySet: + owners = visible_owner_ids(viewer) + if owners is None: + return qs + if not owners: + return qs.none() + city_ids = visible_active_city_site_ids(viewer) + if not city_ids: + return qs.none() + return qs.filter( + kandang__site__user_id__in=owners, + kandang__site__city_site_id__in=city_ids, + ) + + +def filter_cycles_queryset(qs: QuerySet, viewer: User) -> QuerySet: + owners = visible_owner_ids(viewer) + if owners is None: + return qs + if not owners: + return qs.none() + city_ids = visible_active_city_site_ids(viewer) + if not city_ids: + return qs.none() + return qs.filter( + kandang__site__user_id__in=owners, + kandang__site__city_site_id__in=city_ids, + ) diff --git a/backend/apps/accounts/serializers.py b/backend/apps/accounts/serializers.py new file mode 100644 index 0000000..59c1599 --- /dev/null +++ b/backend/apps/accounts/serializers.py @@ -0,0 +1,184 @@ +from django.contrib.auth import get_user_model +from rest_framework import serializers + +from apps.accounts.models import ApiKey + +User = get_user_model() + + +class PkAsIdMixin(serializers.Serializer): + """Keep JSON `id` stable after ERD-named primary keys.""" + + id = serializers.IntegerField(source="pk", read_only=True) + + +class UserSerializer(PkAsIdMixin, serializers.ModelSerializer): + managed_by = serializers.PrimaryKeyRelatedField( + queryset=User.objects.filter(status__in=["buh", "bu_admin"]), + allow_null=True, + required=False, + ) + managed_by_name = serializers.CharField( + source="managed_by.user_name", read_only=True, allow_null=True + ) + managed_by_pending = serializers.PrimaryKeyRelatedField(read_only=True) + managed_by_pending_name = serializers.CharField( + source="managed_by_pending.user_name", read_only=True, allow_null=True + ) + + class Meta: + model = User + fields = [ + "id", + "user_name", + "status", + "is_superuser", + "managed_by", + "managed_by_name", + "managed_by_pending", + "managed_by_pending_name", + "managed_by_requested_at", + "created_at", + "updated_at", + ] + read_only_fields = [ + "id", + "is_superuser", + "managed_by_name", + "managed_by_pending", + "managed_by_pending_name", + "managed_by_requested_at", + "created_at", + "updated_at", + ] + + +class UserWriteSerializer(PkAsIdMixin, serializers.ModelSerializer): + """Create/update users for Account Admin. Password required on create.""" + + password = serializers.CharField(write_only=True, required=False, allow_blank=False) + managed_by = serializers.PrimaryKeyRelatedField( + queryset=User.objects.filter(status__in=["buh", "bu_admin"]), + allow_null=True, + required=False, + ) + managed_by_name = serializers.CharField( + source="managed_by.user_name", read_only=True, allow_null=True + ) + managed_by_pending = serializers.PrimaryKeyRelatedField(read_only=True) + managed_by_pending_name = serializers.CharField( + source="managed_by_pending.user_name", read_only=True, allow_null=True + ) + + class Meta: + model = User + fields = [ + "id", + "user_name", + "status", + "is_superuser", + "password", + "managed_by", + "managed_by_name", + "managed_by_pending", + "managed_by_pending_name", + "managed_by_requested_at", + "created_at", + "updated_at", + ] + read_only_fields = [ + "id", + "is_superuser", + "managed_by_name", + "managed_by_pending", + "managed_by_pending_name", + "managed_by_requested_at", + "created_at", + "updated_at", + ] + + def validate_password(self, value: str) -> str: + if value is not None and not str(value).strip(): + raise serializers.ValidationError("Password cannot be blank.") + return value + + def validate(self, attrs): + if self.instance is None and not attrs.get("password"): + raise serializers.ValidationError({"password": "This field is required."}) + + new_status = attrs.get("status") + if new_status == User.STATUS_SUPERUSER: + raise serializers.ValidationError( + {"status": "Superuser accounts cannot be created or assigned here."} + ) + + request = self.context.get("request") + actor = getattr(request, "user", None) if request else None + instance = self.instance + if ( + instance is not None + and actor is not None + and getattr(actor, "is_authenticated", False) + and instance.pk == actor.pk + and "status" in attrs + and attrs["status"] != instance.status + ): + if attrs["status"] == User.STATUS_INACTIVE: + raise serializers.ValidationError( + {"status": "You cannot deactivate your own account."} + ) + raise serializers.ValidationError( + {"status": "You cannot change your own account status."} + ) + return attrs + + def create(self, validated_data): + password = validated_data.pop("password") + user_name = validated_data.pop("user_name") + return User.objects.create_user( + user_name=user_name, password=password, **validated_data + ) + + def update(self, instance, validated_data): + password = validated_data.pop("password", None) + for attr, value in validated_data.items(): + setattr(instance, attr, value) + if password: + instance.set_password(password) + instance.save() + return instance + + +class SetPasswordSerializer(serializers.Serializer): + password = serializers.CharField(write_only=True, allow_blank=False) + + def validate_password(self, value: str) -> str: + if not str(value).strip(): + raise serializers.ValidationError("Password cannot be blank.") + return value + + +class LoginSerializer(serializers.Serializer): + user_name = serializers.CharField(max_length=30) + password = serializers.CharField(write_only=True) + + +class ApiKeySerializer(serializers.ModelSerializer): + class Meta: + model = ApiKey + fields = [ + "id", + "name", + "prefix", + "is_active", + "last_used_at", + "created_at", + "updated_at", + "user", + ] + read_only_fields = fields + + +class ApiKeyCreateSerializer(serializers.Serializer): + name = serializers.CharField(max_length=100) + user_id = serializers.IntegerField(required=False) diff --git a/backend/apps/accounts/tests_account_admin.py b/backend/apps/accounts/tests_account_admin.py new file mode 100644 index 0000000..e6c2752 --- /dev/null +++ b/backend/apps/accounts/tests_account_admin.py @@ -0,0 +1,227 @@ +from django.contrib.auth import authenticate +from django.test import TestCase +from rest_framework.test import APIClient + +from apps.accounts.models import User + + +class AccountAdminModelTests(TestCase): + def test_account_admin_flags_and_executive(self): + user = User.objects.create_user( + user_name="acct1", + password="secret", + status=User.STATUS_ACCOUNT_ADMIN, + ) + self.assertTrue(user.is_active) + self.assertFalse(user.is_superuser) + self.assertTrue(user.is_executive) + + def test_inactive_clears_flags(self): + user = User.objects.create_user( + user_name="acct2", + password="secret", + status=User.STATUS_ACCOUNT_ADMIN, + ) + user.status = User.STATUS_INACTIVE + user.save() + user.refresh_from_db() + self.assertFalse(user.is_active) + self.assertFalse(user.is_superuser) + + def test_director_admin_is_not_superuser(self): + user = User.objects.create_user( + user_name="diradmin1", + password="secret", + status=User.STATUS_DIRECTOR_ADMIN, + ) + self.assertEqual(user.status, User.STATUS_DIRECTOR_ADMIN) + self.assertFalse(user.is_superuser) + + +class AccountAdminApiTests(TestCase): + def setUp(self): + self.client = APIClient() + self.account_admin = User.objects.create_user( + user_name="acctadmin", + password="acct123", + status=User.STATUS_ACCOUNT_ADMIN, + ) + self.gm = User.objects.create_user( + user_name="gm1", password="gm123", status=User.STATUS_GM + ) + self.buh = User.objects.create_user( + user_name="buh1", password="buh123", status=User.STATUS_BUH + ) + self.director = User.objects.create_user( + user_name="dir1", password="dir123", status=User.STATUS_DIRECTOR + ) + self.superuser = User.objects.create_superuser( + user_name="admin1", + password="admin123", + ) + self.assertTrue(self.superuser.is_superuser) + self.assertEqual(self.superuser.status, User.STATUS_SUPERUSER) + + def test_account_admin_creates_user_with_password(self): + self.client.force_authenticate(self.account_admin) + response = self.client.post( + "/api/v1/users/", + { + "user_name": "newgm", + "status": User.STATUS_GM, + "password": "temp-pass", + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + created = User.objects.get(user_name="newgm") + self.assertEqual(created.status, User.STATUS_GM) + self.assertIsNotNone( + authenticate(username="newgm", password="temp-pass") + ) + + def test_account_admin_create_requires_password(self): + self.client.force_authenticate(self.account_admin) + response = self.client.post( + "/api/v1/users/", + {"user_name": "nopass", "status": User.STATUS_GM}, + format="json", + ) + self.assertEqual(response.status_code, 400) + self.assertIn("password", response.data) + + def test_gm_cannot_create_user(self): + self.client.force_authenticate(self.gm) + response = self.client.post( + "/api/v1/users/", + { + "user_name": "blocked", + "status": User.STATUS_GM, + "password": "x", + }, + format="json", + ) + self.assertEqual(response.status_code, 403) + + def test_account_admin_lists_all_users(self): + self.client.force_authenticate(self.account_admin) + response = self.client.get("/api/v1/users/") + self.assertEqual(response.status_code, 200) + names = {row["user_name"] for row in response.data["results"]} + self.assertIn("gm1", names) + self.assertIn("buh1", names) + self.assertIn("dir1", names) + self.assertIn("acctadmin", names) + + def test_account_admin_set_password(self): + self.client.force_authenticate(self.account_admin) + response = self.client.post( + f"/api/v1/users/{self.gm.pk}/set-password/", + {"password": "new-gm-pass"}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertIsNotNone( + authenticate(username="gm1", password="new-gm-pass") + ) + self.assertIsNone(authenticate(username="gm1", password="gm123")) + + def test_account_admin_deactivate_blocks_login(self): + self.client.force_authenticate(self.account_admin) + response = self.client.patch( + f"/api/v1/users/{self.gm.pk}/", + {"status": User.STATUS_INACTIVE}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + self.gm.refresh_from_db() + self.assertFalse(self.gm.is_active) + self.assertIsNone(authenticate(username="gm1", password="gm123")) + + def test_buh_and_director_cannot_set_password(self): + for actor in (self.buh, self.director): + self.client.force_authenticate(actor) + response = self.client.post( + f"/api/v1/users/{self.gm.pk}/set-password/", + {"password": "hack"}, + format="json", + ) + self.assertEqual(response.status_code, 403, actor.user_name) + + def test_superuser_break_glass_create(self): + self.client.force_authenticate(self.superuser) + response = self.client.post( + "/api/v1/users/", + { + "user_name": "breakglass", + "status": User.STATUS_BUH, + "password": "bg-pass", + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + + def test_account_admin_cannot_deactivate_self(self): + self.client.force_authenticate(self.account_admin) + response = self.client.patch( + f"/api/v1/users/{self.account_admin.pk}/", + {"status": User.STATUS_INACTIVE}, + format="json", + ) + self.assertEqual(response.status_code, 400) + self.assertIn("status", response.data) + self.account_admin.refresh_from_db() + self.assertEqual(self.account_admin.status, User.STATUS_ACCOUNT_ADMIN) + self.assertTrue(self.account_admin.is_active) + + def test_account_admin_cannot_change_own_status(self): + self.client.force_authenticate(self.account_admin) + response = self.client.patch( + f"/api/v1/users/{self.account_admin.pk}/", + {"status": User.STATUS_GM}, + format="json", + ) + self.assertEqual(response.status_code, 400) + self.assertIn("status", response.data) + self.account_admin.refresh_from_db() + self.assertEqual(self.account_admin.status, User.STATUS_ACCOUNT_ADMIN) + + def test_peer_account_admin_can_deactivate_other_account_admin(self): + peer = User.objects.create_user( + user_name="acctadmin2", + password="acct123", + status=User.STATUS_ACCOUNT_ADMIN, + ) + self.client.force_authenticate(self.account_admin) + response = self.client.patch( + f"/api/v1/users/{peer.pk}/", + {"status": User.STATUS_INACTIVE}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + peer.refresh_from_db() + self.assertEqual(peer.status, User.STATUS_INACTIVE) + self.assertFalse(peer.is_active) + + def test_superuser_hidden_from_user_list(self): + User.objects.create_superuser(user_name="hidden_su", password="x") + self.client.force_authenticate(self.account_admin) + response = self.client.get("/api/v1/users/") + self.assertEqual(response.status_code, 200) + names = {row["user_name"] for row in response.data["results"]} + self.assertNotIn("hidden_su", names) + self.assertNotIn("admin1", names) + + def test_cannot_assign_superuser_status_via_api(self): + self.client.force_authenticate(self.account_admin) + response = self.client.post( + "/api/v1/users/", + { + "user_name": "bad_su", + "status": User.STATUS_SUPERUSER, + "password": "x", + }, + format="json", + ) + self.assertEqual(response.status_code, 400) + self.assertIn("status", response.data) diff --git a/backend/apps/accounts/tests_managed_by.py b/backend/apps/accounts/tests_managed_by.py new file mode 100644 index 0000000..e52f1c0 --- /dev/null +++ b/backend/apps/accounts/tests_managed_by.py @@ -0,0 +1,99 @@ +from django.test import TestCase +from rest_framework.test import APIClient + +from apps.accounts.models import User + + +class ManagedByRequestTests(TestCase): + def setUp(self): + self.client = APIClient() + self.buh = User.objects.create_user( + user_name="buh1", password="x", status=User.STATUS_BUH + ) + self.buh_other = User.objects.create_user( + user_name="buh2", password="x", status=User.STATUS_BUH + ) + self.gm = User.objects.create_user( + user_name="gm1", password="x", status=User.STATUS_GM + ) + + def test_gm_requests_and_buh_approves(self): + self.client.force_authenticate(self.gm) + response = self.client.post( + "/api/v1/users/request-managed-by/", {"buh_id": self.buh.pk}, format="json" + ) + self.assertEqual(response.status_code, 200) + self.gm.refresh_from_db() + self.assertIsNone(self.gm.managed_by_id) + self.assertEqual(self.gm.managed_by_pending_id, self.buh.pk) + + self.client.force_authenticate(self.buh) + pending = self.client.get("/api/v1/users/pending-managed/") + self.assertEqual(pending.status_code, 200) + self.assertEqual({row["user_name"] for row in pending.data}, {"gm1"}) + + approve = self.client.post(f"/api/v1/users/{self.gm.pk}/approve-managed-by/", {}) + self.assertEqual(approve.status_code, 200) + self.gm.refresh_from_db() + self.assertEqual(self.gm.managed_by_id, self.buh.pk) + self.assertIsNone(self.gm.managed_by_pending_id) + + managed = self.client.get("/api/v1/users/") + self.assertEqual({row["user_name"] for row in managed.data["results"]}, {"gm1"}) + + def test_other_buh_cannot_approve(self): + self.gm.request_managed_by(self.buh) + self.client.force_authenticate(self.buh_other) + response = self.client.post(f"/api/v1/users/{self.gm.pk}/approve-managed-by/", {}) + self.assertEqual(response.status_code, 404) + self.gm.refresh_from_db() + self.assertIsNone(self.gm.managed_by_id) + self.assertEqual(self.gm.managed_by_pending_id, self.buh.pk) + + def test_gm_can_cancel_request(self): + self.gm.request_managed_by(self.buh) + self.client.force_authenticate(self.gm) + response = self.client.post("/api/v1/users/cancel-managed-by-request/", {}) + self.assertEqual(response.status_code, 200) + self.gm.refresh_from_db() + self.assertIsNone(self.gm.managed_by_pending_id) + + def test_gm_lists_buhs_only(self): + User.objects.create_user( + user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN + ) + self.client.force_authenticate(self.gm) + response = self.client.get("/api/v1/users/buhs/") + self.assertEqual(response.status_code, 200) + names = {row["user_name"] for row in response.data} + self.assertEqual(names, {"buh1", "buh2"}) + + def test_gm_admin_cannot_request_buh(self): + gm_admin = User.objects.create_user( + user_name="gma1", password="x", status=User.STATUS_GM_ADMIN + ) + self.client.force_authenticate(gm_admin) + response = self.client.post( + "/api/v1/users/request-managed-by/", {"buh_id": self.buh.pk}, format="json" + ) + self.assertEqual(response.status_code, 403) + + def test_gm_cannot_request_bu_admin(self): + bu_admin = User.objects.create_user( + user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN + ) + self.client.force_authenticate(self.gm) + response = self.client.post( + "/api/v1/users/request-managed-by/", {"buh_id": bu_admin.pk}, format="json" + ) + self.assertEqual(response.status_code, 400) + + def test_bu_admin_cannot_approve(self): + bu_admin = User.objects.create_user( + user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN + ) + self.gm.managed_by_pending = bu_admin + self.gm.save(update_fields=["managed_by_pending", "updated_at"]) + self.client.force_authenticate(bu_admin) + response = self.client.post(f"/api/v1/users/{self.gm.pk}/approve-managed-by/", {}) + self.assertEqual(response.status_code, 403) diff --git a/backend/apps/accounts/tests_scoping.py b/backend/apps/accounts/tests_scoping.py new file mode 100644 index 0000000..ada55f2 --- /dev/null +++ b/backend/apps/accounts/tests_scoping.py @@ -0,0 +1,118 @@ +from django.test import TestCase +from rest_framework.test import APIClient + +from apps.accounts.models import User +from apps.farms.models import Kandang, Site +from apps.sync.models import CitySite + + +class VisibilityScopeTests(TestCase): + def setUp(self): + self.client = APIClient() + self.director = User.objects.create_user( + user_name="dir1", password="x", status=User.STATUS_DIRECTOR + ) + self.buh = User.objects.create_user( + user_name="buh1", password="x", status=User.STATUS_BUH + ) + self.buh_other = User.objects.create_user( + user_name="buh2", password="x", status=User.STATUS_BUH + ) + self.gm = User.objects.create_user( + user_name="gm1", password="x", status=User.STATUS_GM, managed_by=self.buh + ) + self.gm_other = User.objects.create_user( + user_name="gm2", + password="x", + status=User.STATUS_GM, + managed_by=self.buh_other, + ) + self.city_a = CitySite.objects.create( + code="a", + name="City A", + api_base_url="https://a.example/api/v1", + registered_by=self.gm, + ) + self.city_b = CitySite.objects.create( + code="b", + name="City B", + api_base_url="https://b.example/api/v1", + registered_by=self.gm_other, + ) + self.site = Site.objects.create( + site_name="Site A", user=self.gm, city_site=self.city_a + ) + self.site_other = Site.objects.create( + site_name="Site B", user=self.gm_other, city_site=self.city_b + ) + self.orphan = Site.objects.create(site_name="Orphan Seed", user=self.gm) + Kandang.objects.create(kandang_name="K1", site=self.site) + Kandang.objects.create(kandang_name="K2", site=self.site_other) + + def test_director_sees_all_sites(self): + self.client.force_authenticate(self.director) + response = self.client.get("/api/v1/sites/") + self.assertEqual(response.status_code, 200) + names = {row["site_name"] for row in response.data["results"]} + self.assertEqual(names, {"Site A", "Site B", "Orphan Seed"}) + + def test_buh_sees_only_managed_gm_registered_sites(self): + self.client.force_authenticate(self.buh) + response = self.client.get("/api/v1/sites/") + self.assertEqual(response.status_code, 200) + names = {row["site_name"] for row in response.data["results"]} + self.assertEqual(names, {"Site A"}) + + def test_buh_sees_only_managed_gms(self): + self.client.force_authenticate(self.buh) + response = self.client.get("/api/v1/users/") + self.assertEqual(response.status_code, 200) + names = {row["user_name"] for row in response.data["results"]} + self.assertEqual(names, {"gm1"}) + + def test_gm_sees_own_city_sites_only(self): + self.client.force_authenticate(self.gm) + response = self.client.get("/api/v1/city-sites/") + self.assertEqual(response.status_code, 200) + codes = {row["code"] for row in response.data["results"]} + self.assertEqual(codes, {"a"}) + + def test_gm_sees_only_registered_linked_sites(self): + self.client.force_authenticate(self.gm) + response = self.client.get("/api/v1/sites/") + self.assertEqual(response.status_code, 200) + names = {row["site_name"] for row in response.data["results"]} + self.assertEqual(names, {"Site A"}) + + def test_gm_with_empty_registry_sees_no_sites(self): + self.city_a.delete() + self.client.force_authenticate(self.gm) + response = self.client.get("/api/v1/sites/") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data["results"], []) + + def test_registering_city_site_attaches_matching_seed_site(self): + self.client.force_authenticate(self.gm) + response = self.client.post( + "/api/v1/city-sites/", + { + "code": "orphan-seed", + "name": "Orphan Seed", + "api_base_url": "https://orphan.example/api/v1", + "is_active": True, + }, + format="json", + ) + self.assertEqual(response.status_code, 201) + self.orphan.refresh_from_db() + self.assertEqual(self.orphan.city_site_id, response.data["id"]) + listed = self.client.get("/api/v1/sites/") + names = {row["site_name"] for row in listed.data["results"]} + self.assertIn("Orphan Seed", names) + + def test_director_sees_all_city_sites(self): + self.client.force_authenticate(self.director) + response = self.client.get("/api/v1/city-sites/") + self.assertEqual(response.status_code, 200) + codes = {row["code"] for row in response.data["results"]} + self.assertEqual(codes, {"a", "b"}) diff --git a/backend/apps/accounts/urls.py b/backend/apps/accounts/urls.py new file mode 100644 index 0000000..ff844ba --- /dev/null +++ b/backend/apps/accounts/urls.py @@ -0,0 +1,23 @@ +from django.urls import path +from rest_framework.routers import DefaultRouter + +from apps.accounts.views import ( + ApiKeyViewSet, + CsrfView, + LoginView, + LogoutView, + MeView, + UserViewSet, +) + +router = DefaultRouter() +router.register("users", UserViewSet, basename="user") +router.register("api-keys", ApiKeyViewSet, basename="api-key") + +urlpatterns = [ + path("auth/csrf/", CsrfView.as_view(), name="auth-csrf"), + path("auth/login/", LoginView.as_view(), name="auth-login"), + path("auth/logout/", LogoutView.as_view(), name="auth-logout"), + path("auth/me/", MeView.as_view(), name="auth-me"), + *router.urls, +] diff --git a/backend/apps/accounts/views.py b/backend/apps/accounts/views.py new file mode 100644 index 0000000..9962402 --- /dev/null +++ b/backend/apps/accounts/views.py @@ -0,0 +1,258 @@ +from django.contrib.auth import authenticate, login, logout +from django.core.exceptions import ValidationError +from django.middleware.csrf import get_token +from django.views.decorators.csrf import ensure_csrf_cookie +from django.utils.decorators import method_decorator +from rest_framework import permissions, status, viewsets +from rest_framework.decorators import action +from rest_framework.response import Response +from rest_framework.views import APIView + +from apps.accounts.models import ApiKey, User +from apps.accounts.permissions import IsExecutive +from apps.accounts.scoping import filter_users_queryset +from apps.accounts.serializers import ( + ApiKeyCreateSerializer, + ApiKeySerializer, + LoginSerializer, + SetPasswordSerializer, + UserSerializer, + UserWriteSerializer, +) + + +def _validation_detail(exc: ValidationError): + if hasattr(exc, "message_dict"): + return exc.message_dict + if hasattr(exc, "messages"): + return "; ".join(str(m) for m in exc.messages) + return str(getattr(exc, "message", exc)) + + +class IsOwnerOrStaff(permissions.BasePermission): + def has_object_permission(self, request, view, obj): + if request.user.is_superuser: + return True + return getattr(obj, "user_id", None) == request.user.pk or obj == request.user + + +class IsAdminUser(permissions.BasePermission): + """Write access for Account Admin or Django superuser break-glass.""" + + def has_permission(self, request, view): + from apps.accounts.permissions import can_manage_users + + return can_manage_users(request.user) + + +class UserViewSet(viewsets.ModelViewSet): + """ + List/retrieve: scoped for executives (BUH → managed GMs; director / account_admin → all). + Create/update/delete/set-password: Account Admin or superuser. + + GM/GM Admin can request a BUH; that BUH can approve/reject. + """ + + serializer_class = UserSerializer + + def get_queryset(self): + qs = User.objects.select_related("managed_by", "managed_by_pending").order_by( + "user_name" + ) + return filter_users_queryset(qs, self.request.user) + + def get_serializer_class(self): + if self.action in {"create", "update", "partial_update"}: + return UserWriteSerializer + return UserSerializer + + def get_permissions(self): + if self.action in { + "list", + "retrieve", + "buhs", + "pending_managed", + "request_managed_by", + "cancel_managed_by_request", + "approve_managed_by", + "reject_managed_by", + }: + return [IsExecutive()] + return [IsAdminUser()] + + @action(detail=True, methods=["post"], url_path="set-password") + def set_password(self, request, pk=None): + user = self.get_object() + serializer = SetPasswordSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + user.set_password(serializer.validated_data["password"]) + user.save(update_fields=["password", "updated_at"]) + return Response(UserSerializer(user).data) + + @action(detail=False, methods=["get"], url_path="buhs") + def buhs(self, request): + """List BUH accounts a GM can request to report under (not BU Admin).""" + if request.user.status != User.STATUS_GM and not request.user.is_superuser: + if request.user.status not in { + User.STATUS_DIRECTOR, + User.STATUS_DIRECTOR_ADMIN, + User.STATUS_BUH, + User.STATUS_BU_ADMIN, + }: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + rows = User.objects.filter( + status=User.STATUS_BUH, + is_active=True, + ).order_by("user_name") + return Response(UserSerializer(rows, many=True).data) + + @action(detail=False, methods=["get"], url_path="pending-managed") + def pending_managed(self, request): + """BUH only: GMs who requested to report under this account.""" + if request.user.status != User.STATUS_BUH: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + rows = User.objects.filter( + managed_by_pending=request.user, + status=User.STATUS_GM, + ).select_related("managed_by", "managed_by_pending").order_by("user_name") + return Response(UserSerializer(rows, many=True).data) + + @action(detail=False, methods=["post"], url_path="request-managed-by") + def request_managed_by(self, request): + """GM only: request to report under a BUH (not BU Admin).""" + if request.user.status != User.STATUS_GM: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + buh_id = request.data.get("buh_id") + try: + buh = User.objects.get( + pk=buh_id, + status=User.STATUS_BUH, + is_active=True, + ) + except (User.DoesNotExist, TypeError, ValueError): + return Response({"detail": "Invalid buh_id."}, status=status.HTTP_400_BAD_REQUEST) + try: + request.user.request_managed_by(buh) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + return Response(UserSerializer(request.user).data) + + @action(detail=False, methods=["post"], url_path="cancel-managed-by-request") + def cancel_managed_by_request(self, request): + if request.user.status != User.STATUS_GM: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + request.user.cancel_managed_by_request() + return Response(UserSerializer(request.user).data) + + @action(detail=True, methods=["post"], url_path="approve-managed-by") + def approve_managed_by(self, request, pk=None): + if request.user.status != User.STATUS_BUH: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + gm = User.objects.filter( + pk=pk, + managed_by_pending=request.user, + status=User.STATUS_GM, + ).first() + if gm is None: + return Response({"detail": "Not found."}, status=status.HTTP_404_NOT_FOUND) + try: + gm.approve_managed_by(request.user) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + return Response(UserSerializer(gm).data) + + @action(detail=True, methods=["post"], url_path="reject-managed-by") + def reject_managed_by(self, request, pk=None): + if request.user.status != User.STATUS_BUH: + return Response({"detail": "Not allowed."}, status=status.HTTP_403_FORBIDDEN) + gm = User.objects.filter( + pk=pk, + managed_by_pending=request.user, + status=User.STATUS_GM, + ).first() + if gm is None: + return Response({"detail": "Not found."}, status=status.HTTP_404_NOT_FOUND) + try: + gm.reject_managed_by(request.user) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + return Response(UserSerializer(gm).data) + + +class ApiKeyViewSet(viewsets.ModelViewSet): + http_method_names = ["get", "post", "delete", "head", "options"] + + def get_queryset(self): + qs = ApiKey.objects.select_related("user").order_by("-created_at") + if self.request.user.is_superuser: + return qs + return qs.filter(user=self.request.user) + + def get_serializer_class(self): + if self.action == "create": + return ApiKeyCreateSerializer + return ApiKeySerializer + + def get_permissions(self): + return [permissions.IsAuthenticated()] + + def create(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + name = serializer.validated_data["name"] + user = request.user + if request.user.is_superuser and serializer.validated_data.get("user_id"): + user = User.objects.get(pk=serializer.validated_data["user_id"]) + api_key, raw = ApiKey.generate(user=user, name=name) + data = ApiKeySerializer(api_key).data + data["raw_key"] = raw + return Response(data, status=status.HTTP_201_CREATED) + + def perform_destroy(self, instance): + if ( + not self.request.user.is_superuser + and instance.user_id != self.request.user.pk + ): + raise permissions.PermissionDenied() + instance.delete() + + +@method_decorator(ensure_csrf_cookie, name="dispatch") +class CsrfView(APIView): + permission_classes = [permissions.AllowAny] + authentication_classes = [] + + def get(self, request): + return Response({"csrfToken": get_token(request)}) + + +class LoginView(APIView): + permission_classes = [permissions.AllowAny] + authentication_classes = [] + + def post(self, request): + serializer = LoginSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + user = authenticate( + request, + username=serializer.validated_data["user_name"], + password=serializer.validated_data["password"], + ) + if user is None: + return Response( + {"detail": "Invalid credentials"}, + status=status.HTTP_401_UNAUTHORIZED, + ) + login(request, user) + return Response(UserSerializer(user).data) + + +class LogoutView(APIView): + def post(self, request): + logout(request) + return Response(status=status.HTTP_204_NO_CONTENT) + + +class MeView(APIView): + def get(self, request): + return Response(UserSerializer(request.user).data) diff --git a/backend/apps/farms/__init__.py b/backend/apps/farms/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/farms/apps.py b/backend/apps/farms/apps.py new file mode 100644 index 0000000..c3c89c7 --- /dev/null +++ b/backend/apps/farms/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class FarmsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.farms" + label = "farms" + verbose_name = "Farms" diff --git a/backend/apps/farms/migrations/0001_initial.py b/backend/apps/farms/migrations/0001_initial.py new file mode 100644 index 0000000..ff17df3 --- /dev/null +++ b/backend/apps/farms/migrations/0001_initial.py @@ -0,0 +1,91 @@ +# Generated by Django 5.2.17 on 2026-08-18 08:01 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Cycle', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('total_days', models.IntegerField()), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('doc_in_weight', models.IntegerField()), + ('doc_in_count', models.IntegerField()), + ('status', models.CharField(choices=[('active', 'Active'), ('closed', 'Closed')], default='active', max_length=30)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'cycles', + 'ordering': ['-start_date'], + }, + ), + migrations.CreateModel( + name='Flock', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('flock_name', models.CharField(max_length=30)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='flock_set', to='farms.cycle')), + ], + options={ + 'db_table': 'flock', + 'ordering': ['flock_name'], + }, + ), + migrations.AddField( + model_name='cycle', + name='flock', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cycles', to='farms.flock'), + ), + migrations.CreateModel( + name='Site', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('site_name', models.CharField(max_length=30)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sites', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'sites', + 'ordering': ['site_name'], + }, + ), + migrations.CreateModel( + name='Kandang', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('kandang_name', models.CharField(max_length=30)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='kandangs', to='farms.site')), + ], + options={ + 'db_table': 'kandang', + 'ordering': ['kandang_name'], + }, + ), + migrations.AddField( + model_name='cycle', + name='kandang', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cycles', to='farms.kandang'), + ), + migrations.AddConstraint( + model_name='cycle', + constraint=models.CheckConstraint(condition=models.Q(('end_date__gte', models.F('start_date'))), name='chk_cycles_date_range'), + ), + ] diff --git a/backend/apps/farms/migrations/0002_cycle_requires_flock.py b/backend/apps/farms/migrations/0002_cycle_requires_flock.py new file mode 100644 index 0000000..aaa1a03 --- /dev/null +++ b/backend/apps/farms/migrations/0002_cycle_requires_flock.py @@ -0,0 +1,81 @@ +# Generated by Django 5.2.17 on 2026-08-19 + +import django.db.models.deletion +from django.db import migrations, models + + +def _column_names(connection, table): + with connection.cursor() as cursor: + if connection.vendor == "sqlite": + cursor.execute(f"PRAGMA table_info({table})") + return {row[1] for row in cursor.fetchall()} + cursor.execute( + """ + SELECT column_name + FROM information_schema.columns + WHERE table_name = %s + """, + [table], + ) + return {row[0] for row in cursor.fetchall()} + + +def ensure_cycle_kandang_id(apps, schema_editor): + connection = schema_editor.connection + if "kandang_id" in _column_names(connection, "cycles"): + return + with connection.cursor() as cursor: + cursor.execute( + "ALTER TABLE cycles ADD COLUMN kandang_id bigint NULL REFERENCES kandang(id)" + ) + + +def backfill_cycle_flocks(apps, schema_editor): + Cycle = apps.get_model("farms", "Cycle") + Flock = apps.get_model("farms", "Flock") + for cycle_id in Cycle.objects.filter(flock_id__isnull=True).values_list("pk", flat=True): + flock = Flock.objects.create(flock_name=f"Cycle {cycle_id}") + Cycle.objects.filter(pk=cycle_id).update(flock_id=flock.pk) + Flock.objects.filter(pk=flock.pk).update(cycle_id=cycle_id) + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0001_initial"), + ] + + operations = [ + migrations.RunPython(ensure_cycle_kandang_id, migrations.RunPython.noop), + migrations.RunPython(backfill_cycle_flocks, migrations.RunPython.noop), + migrations.AlterField( + model_name="cycle", + name="flock", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="cycles", + to="farms.flock", + ), + ), + migrations.AlterField( + model_name="cycle", + name="status", + field=models.CharField( + choices=[("active", "Active"), ("closed", "Closed")], + db_index=True, + default="active", + max_length=30, + ), + ), + migrations.AlterField( + model_name="flock", + name="cycle", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="flock_set", + to="farms.cycle", + ), + ), + ] diff --git a/backend/apps/farms/migrations/0003_flock_cycle_nullable.py b/backend/apps/farms/migrations/0003_flock_cycle_nullable.py new file mode 100644 index 0000000..ea1281f --- /dev/null +++ b/backend/apps/farms/migrations/0003_flock_cycle_nullable.py @@ -0,0 +1,52 @@ +# Generated by Django 5.2.17 on 2026-08-19 + +from django.db import migrations + + +def _sqlite_flock_cycle_notnull(connection): + with connection.cursor() as cursor: + cursor.execute("PRAGMA table_info(flock)") + cols = {row[1]: row for row in cursor.fetchall()} + cycle_col = cols.get("cycle_id") + return bool(cycle_col and cycle_col[3] == 1) + + +def make_flock_cycle_nullable(apps, schema_editor): + connection = schema_editor.connection + if connection.vendor != "sqlite": + return + if not _sqlite_flock_cycle_notnull(connection): + return + with connection.cursor() as cursor: + cursor.execute("PRAGMA foreign_keys=OFF") + cursor.execute("ALTER TABLE flock RENAME TO flock_old") + cursor.execute( + """ + CREATE TABLE flock ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + flock_name varchar(30) NOT NULL, + created_at datetime NOT NULL, + updated_at datetime NOT NULL, + cycle_id bigint NULL REFERENCES cycles(id) + ) + """ + ) + cursor.execute( + """ + INSERT INTO flock (id, flock_name, created_at, updated_at, cycle_id) + SELECT id, flock_name, created_at, updated_at, cycle_id FROM flock_old + """ + ) + cursor.execute("DROP TABLE flock_old") + cursor.execute("PRAGMA foreign_keys=ON") + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0002_cycle_requires_flock"), + ] + + operations = [ + migrations.RunPython(make_flock_cycle_nullable, migrations.RunPython.noop), + ] diff --git a/backend/apps/farms/migrations/0004_retarget_cycles_flock_fk.py b/backend/apps/farms/migrations/0004_retarget_cycles_flock_fk.py new file mode 100644 index 0000000..198f875 --- /dev/null +++ b/backend/apps/farms/migrations/0004_retarget_cycles_flock_fk.py @@ -0,0 +1,59 @@ +# Generated by Django 5.2.17 on 2026-08-19 + +from django.db import migrations + + +def retarget_cycles_flock_fk(apps, schema_editor): + connection = schema_editor.connection + if connection.vendor != "sqlite": + return + with connection.cursor() as cursor: + cursor.execute("SELECT sql FROM sqlite_master WHERE name='cycles'") + row = cursor.fetchone() + if not row or "flock_old" not in (row[0] or ""): + return + cursor.execute("PRAGMA foreign_keys=OFF") + cursor.execute("ALTER TABLE cycles RENAME TO cycles_old") + cursor.execute( + """ + CREATE TABLE cycles ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + total_days integer NOT NULL, + start_date date NOT NULL, + end_date date NOT NULL, + doc_in_weight integer NOT NULL, + doc_in_count integer NOT NULL, + created_at datetime NOT NULL, + updated_at datetime NOT NULL, + flock_id bigint NOT NULL REFERENCES flock(id) DEFERRABLE INITIALLY DEFERRED, + kandang_id bigint NOT NULL REFERENCES kandang(id) DEFERRABLE INITIALLY DEFERRED, + status varchar(30) NOT NULL, + CONSTRAINT chk_cycles_date_range CHECK (end_date >= start_date) + ) + """ + ) + cursor.execute( + """ + INSERT INTO cycles ( + id, total_days, start_date, end_date, doc_in_weight, doc_in_count, + created_at, updated_at, flock_id, kandang_id, status + ) + SELECT + id, total_days, start_date, end_date, doc_in_weight, doc_in_count, + created_at, updated_at, flock_id, kandang_id, status + FROM cycles_old + """ + ) + cursor.execute("DROP TABLE cycles_old") + cursor.execute("PRAGMA foreign_keys=ON") + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0003_flock_cycle_nullable"), + ] + + operations = [ + migrations.RunPython(retarget_cycles_flock_fk, migrations.RunPython.noop), + ] diff --git a/backend/apps/farms/migrations/0005_erd_named_primary_keys.py b/backend/apps/farms/migrations/0005_erd_named_primary_keys.py new file mode 100644 index 0000000..b36a955 --- /dev/null +++ b/backend/apps/farms/migrations/0005_erd_named_primary_keys.py @@ -0,0 +1,16 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0002_erd_named_primary_keys"), + ("farms", "0004_retarget_cycles_flock_fk"), + ] + + operations = [ + migrations.RenameField(model_name="site", old_name="id", new_name="site_id"), + migrations.RenameField(model_name="kandang", old_name="id", new_name="kandang_id"), + migrations.RenameField(model_name="flock", old_name="id", new_name="flock_id"), + migrations.RenameField(model_name="cycle", old_name="id", new_name="cycle_id"), + ] diff --git a/backend/apps/farms/migrations/0006_erd_flock_belongs_to_cycle.py b/backend/apps/farms/migrations/0006_erd_flock_belongs_to_cycle.py new file mode 100644 index 0000000..61193eb --- /dev/null +++ b/backend/apps/farms/migrations/0006_erd_flock_belongs_to_cycle.py @@ -0,0 +1,40 @@ +from django.db import migrations, models +import django.db.models.deletion + + +def backfill_flock_cycle_from_cycles(apps, schema_editor): + Cycle = apps.get_model("farms", "Cycle") + Flock = apps.get_model("farms", "Flock") + + for cycle in Cycle.objects.exclude(flock_id__isnull=True).iterator(): + Flock.objects.filter(pk=cycle.flock_id).update(cycle_id=cycle.pk) + + Flock.objects.filter(cycle_id__isnull=True).delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0005_erd_named_primary_keys"), + ] + + operations = [ + migrations.RunPython(backfill_flock_cycle_from_cycles, migrations.RunPython.noop), + migrations.AlterField( + model_name="flock", + name="cycle", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.cycle", + ), + ), + migrations.RemoveField( + model_name="cycle", + name="flock", + ), + migrations.AlterField( + model_name="cycle", + name="doc_in_weight", + field=models.FloatField(), + ), + ] diff --git a/backend/apps/farms/migrations/0007_cycle_doc_in_weight_int.py b/backend/apps/farms/migrations/0007_cycle_doc_in_weight_int.py new file mode 100644 index 0000000..b7b6acb --- /dev/null +++ b/backend/apps/farms/migrations/0007_cycle_doc_in_weight_int.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0006_erd_flock_belongs_to_cycle"), + ] + + operations = [ + migrations.AlterField( + model_name="cycle", + name="doc_in_weight", + field=models.IntegerField(), + ), + ] diff --git a/backend/apps/farms/migrations/0008_cycle_feed_initial_balance.py b/backend/apps/farms/migrations/0008_cycle_feed_initial_balance.py new file mode 100644 index 0000000..4dd5d28 --- /dev/null +++ b/backend/apps/farms/migrations/0008_cycle_feed_initial_balance.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0007_cycle_doc_in_weight_int"), + ] + + operations = [ + migrations.AddField( + model_name="cycle", + name="feed_initial_balance", + field=models.IntegerField(default=0), + ), + ] \ No newline at end of file diff --git a/backend/apps/farms/migrations/0009_flock_belongs_to_kandang.py b/backend/apps/farms/migrations/0009_flock_belongs_to_kandang.py new file mode 100644 index 0000000..0971efa --- /dev/null +++ b/backend/apps/farms/migrations/0009_flock_belongs_to_kandang.py @@ -0,0 +1,50 @@ +from django.db import migrations, models +import django.db.models.deletion + + +def backfill_flock_kandang(apps, schema_editor): + Flock = apps.get_model("farms", "Flock") + for flock in Flock.objects.select_related("cycle").iterator(): + if flock.cycle_id and flock.kandang_id is None: + flock.kandang_id = flock.cycle.kandang_id + flock.save(update_fields=["kandang_id"]) + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0008_cycle_feed_initial_balance"), + ] + + operations = [ + migrations.AddField( + model_name="flock", + name="kandang", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.kandang", + ), + ), + migrations.RunPython(backfill_flock_kandang, migrations.RunPython.noop), + migrations.AlterField( + model_name="flock", + name="kandang", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.kandang", + ), + ), + migrations.AlterField( + model_name="flock", + name="cycle", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="flocks", + to="farms.cycle", + ), + ), + ] diff --git a/backend/apps/farms/migrations/0010_restore_flock_cycle_erd.py b/backend/apps/farms/migrations/0010_restore_flock_cycle_erd.py new file mode 100644 index 0000000..4ddd88f --- /dev/null +++ b/backend/apps/farms/migrations/0010_restore_flock_cycle_erd.py @@ -0,0 +1,32 @@ +from django.db import migrations, models +import django.db.models.deletion + + +def remove_orphan_flocks(apps, schema_editor): + Flock = apps.get_model("farms", "Flock") + Flock.objects.filter(cycle_id__isnull=True).delete() + + +class Migration(migrations.Migration): + atomic = False + + dependencies = [ + ("farms", "0009_flock_belongs_to_kandang"), + ] + + operations = [ + migrations.RunPython(remove_orphan_flocks, migrations.RunPython.noop), + migrations.RemoveField( + model_name="flock", + name="kandang", + ), + migrations.AlterField( + model_name="flock", + name="cycle", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.cycle", + ), + ), + ] diff --git a/backend/apps/farms/migrations/0011_flock_belongs_to_kandang.py b/backend/apps/farms/migrations/0011_flock_belongs_to_kandang.py new file mode 100644 index 0000000..567c00c --- /dev/null +++ b/backend/apps/farms/migrations/0011_flock_belongs_to_kandang.py @@ -0,0 +1,45 @@ +from django.db import migrations, models +import django.db.models.deletion + + +def backfill_flock_kandang_from_cycle(apps, schema_editor): + Flock = apps.get_model("farms", "Flock") + for flock in Flock.objects.select_related("cycle").iterator(): + if flock.cycle_id and flock.kandang_id is None: + flock.kandang_id = flock.cycle.kandang_id + flock.save(update_fields=["kandang_id"]) + + +class Migration(migrations.Migration): + atomic = False + + dependencies = [ + ("farms", "0010_restore_flock_cycle_erd"), + ] + + operations = [ + migrations.AddField( + model_name="flock", + name="kandang", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.kandang", + ), + ), + migrations.RunPython(backfill_flock_kandang_from_cycle, migrations.RunPython.noop), + migrations.AlterField( + model_name="flock", + name="kandang", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="flocks", + to="farms.kandang", + ), + ), + migrations.RemoveField( + model_name="flock", + name="cycle", + ), + ] diff --git a/backend/apps/farms/migrations/0012_cycle_feed_initial_balance_date.py b/backend/apps/farms/migrations/0012_cycle_feed_initial_balance_date.py new file mode 100644 index 0000000..c3b0d8a --- /dev/null +++ b/backend/apps/farms/migrations/0012_cycle_feed_initial_balance_date.py @@ -0,0 +1,15 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0011_flock_belongs_to_kandang"), + ] + + operations = [ + migrations.AddField( + model_name="cycle", + name="feed_initial_balance_date", + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/backend/apps/farms/migrations/0013_kandang_feed_in_button_url.py b/backend/apps/farms/migrations/0013_kandang_feed_in_button_url.py new file mode 100644 index 0000000..888496f --- /dev/null +++ b/backend/apps/farms/migrations/0013_kandang_feed_in_button_url.py @@ -0,0 +1,15 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0012_cycle_feed_initial_balance_date"), + ] + + operations = [ + migrations.AddField( + model_name="kandang", + name="feed_in_button_url", + field=models.URLField(blank=True, default="", max_length=500), + ), + ] diff --git a/backend/apps/farms/migrations/0014_kandang_feed_in_button_urls.py b/backend/apps/farms/migrations/0014_kandang_feed_in_button_urls.py new file mode 100644 index 0000000..84bed4f --- /dev/null +++ b/backend/apps/farms/migrations/0014_kandang_feed_in_button_urls.py @@ -0,0 +1,29 @@ +from django.db import migrations, models + + +def migrate_single_url_to_list(apps, schema_editor): + Kandang = apps.get_model("farms", "Kandang") + for kandang in Kandang.objects.exclude(feed_in_button_url="").exclude(feed_in_button_url__isnull=True): + url = (kandang.feed_in_button_url or "").strip() + if url: + kandang.feed_in_button_urls = [{"label": "", "url": url}] + kandang.save(update_fields=["feed_in_button_urls"]) + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0013_kandang_feed_in_button_url"), + ] + + operations = [ + migrations.AddField( + model_name="kandang", + name="feed_in_button_urls", + field=models.JSONField(blank=True, default=list), + ), + migrations.RunPython(migrate_single_url_to_list, migrations.RunPython.noop), + migrations.RemoveField( + model_name="kandang", + name="feed_in_button_url", + ), + ] diff --git a/backend/apps/farms/migrations/0015_cycle_close_approval.py b/backend/apps/farms/migrations/0015_cycle_close_approval.py new file mode 100644 index 0000000..764508a --- /dev/null +++ b/backend/apps/farms/migrations/0015_cycle_close_approval.py @@ -0,0 +1,31 @@ +# Generated by Django 5.1 for HQ GM cycle-close approval + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0005_executive_roles"), + ("farms", "0014_kandang_feed_in_button_urls"), + ] + + operations = [ + migrations.AddField( + model_name="cycle", + name="close_approved_at", + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name="cycle", + name="close_approved_by", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="approved_cycle_closes", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/backend/apps/farms/migrations/0016_cycle_close_request_channel.py b/backend/apps/farms/migrations/0016_cycle_close_request_channel.py new file mode 100644 index 0000000..a13e2e1 --- /dev/null +++ b/backend/apps/farms/migrations/0016_cycle_close_request_channel.py @@ -0,0 +1,109 @@ +# Generated manually for cycle close request channel + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +def null_end_dates_for_open_cycles(apps, schema_editor): + Cycle = apps.get_model("farms", "Cycle") + Cycle.objects.exclude(status="closed").update(end_date=None) + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0015_cycle_close_approval"), + ("sync", "0002_citysite_registered_by"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RemoveConstraint( + model_name="cycle", + name="chk_cycles_date_range", + ), + migrations.AlterField( + model_name="cycle", + name="end_date", + field=models.DateField(blank=True, null=True), + ), + migrations.AlterField( + model_name="cycle", + name="total_days", + field=models.IntegerField(default=1), + ), + migrations.AlterField( + model_name="cycle", + name="status", + field=models.CharField( + choices=[ + ("active", "Active"), + ("pending_close", "Pending close"), + ("closed", "Closed"), + ], + db_index=True, + default="active", + max_length=30, + ), + ), + migrations.AddField( + model_name="cycle", + name="city_site", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="mirrored_cycles", + to="sync.citysite", + ), + ), + migrations.AddField( + model_name="cycle", + name="source_cycle_id", + field=models.BigIntegerField( + blank=True, + help_text="cycle_id on the city dashboard-cpsp deployment", + null=True, + ), + ), + migrations.AddField( + model_name="cycle", + name="proposed_end_date", + field=models.DateField(blank=True, null=True), + ), + migrations.AddField( + model_name="cycle", + name="close_requested_at", + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name="cycle", + name="close_requested_by", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="requested_cycle_closes", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddConstraint( + model_name="cycle", + constraint=models.CheckConstraint( + condition=models.Q(("end_date__isnull", True)) + | models.Q(("end_date__gte", models.F("start_date"))), + name="chk_cycles_date_range", + ), + ), + migrations.AddConstraint( + model_name="cycle", + constraint=models.UniqueConstraint( + condition=models.Q( + ("city_site__isnull", False), ("source_cycle_id__isnull", False) + ), + fields=("city_site", "source_cycle_id"), + name="uniq_cycle_city_source", + ), + ), + migrations.RunPython(null_end_dates_for_open_cycles, migrations.RunPython.noop), + ] diff --git a/backend/apps/farms/migrations/0017_site_city_site.py b/backend/apps/farms/migrations/0017_site_city_site.py new file mode 100644 index 0000000..c1e473a --- /dev/null +++ b/backend/apps/farms/migrations/0017_site_city_site.py @@ -0,0 +1,23 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("farms", "0016_cycle_close_request_channel"), + ("sync", "0002_citysite_registered_by"), + ] + + operations = [ + migrations.AddField( + model_name="site", + name="city_site", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="hq_site", + to="sync.citysite", + ), + ), + ] diff --git a/backend/apps/farms/migrations/__init__.py b/backend/apps/farms/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/farms/models.py b/backend/apps/farms/models.py new file mode 100644 index 0000000..118674b --- /dev/null +++ b/backend/apps/farms/models.py @@ -0,0 +1,276 @@ +from datetime import date + +from django.core.exceptions import ValidationError +from django.db import models +from django.utils import timezone + +from apps.accounts.models import User + + +class Site(models.Model): + site_id = models.BigAutoField(primary_key=True) + site_name = models.CharField(max_length=30) + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="sites") + # Linked when GM/GM Admin adds the city dashboard to their Pengaturan view list. + city_site = models.OneToOneField( + "sync.CitySite", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="hq_site", + ) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "sites" + ordering = ["site_name"] + + def __str__(self) -> str: + return self.site_name + + +class Kandang(models.Model): + kandang_id = models.BigAutoField(primary_key=True) + kandang_name = models.CharField(max_length=30) + feed_in_button_urls = models.JSONField(default=list, blank=True) + site = models.ForeignKey(Site, on_delete=models.CASCADE, related_name="kandangs") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "kandang" + ordering = ["kandang_name"] + + def __str__(self) -> str: + return self.kandang_name + + +class Flock(models.Model): + flock_id = models.BigAutoField(primary_key=True) + flock_name = models.CharField(max_length=30) + kandang = models.ForeignKey( + Kandang, + on_delete=models.CASCADE, + related_name="flocks", + ) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "flock" + ordering = ["flock_name"] + + def __str__(self) -> str: + return self.flock_name + + +class Cycle(models.Model): + STATUS_ACTIVE = "active" + STATUS_PENDING_CLOSE = "pending_close" + STATUS_CLOSED = "closed" + STATUS_CHOICES = [ + (STATUS_ACTIVE, "Active"), + (STATUS_PENDING_CLOSE, "Pending close"), + (STATUS_CLOSED, "Closed"), + ] + + cycle_id = models.BigAutoField(primary_key=True) + total_days = models.IntegerField(default=1) + start_date = models.DateField() + end_date = models.DateField(null=True, blank=True) + doc_in_weight = models.IntegerField() + doc_in_count = models.IntegerField() + feed_initial_balance = models.IntegerField(default=0) + feed_initial_balance_date = models.DateField(null=True, blank=True) + status = models.CharField( + max_length=30, choices=STATUS_CHOICES, default=STATUS_ACTIVE, db_index=True + ) + kandang = models.ForeignKey(Kandang, on_delete=models.CASCADE, related_name="cycles") + city_site = models.ForeignKey( + "sync.CitySite", + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="mirrored_cycles", + ) + source_cycle_id = models.BigIntegerField( + null=True, + blank=True, + help_text="cycle_id on the city dashboard-cpsp deployment", + ) + proposed_end_date = models.DateField(null=True, blank=True) + close_requested_at = models.DateTimeField(null=True, blank=True) + close_requested_by = models.ForeignKey( + User, + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="requested_cycle_closes", + ) + close_approved_by = models.ForeignKey( + User, + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="approved_cycle_closes", + ) + close_approved_at = models.DateTimeField(null=True, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "cycles" + ordering = ["-start_date"] + constraints = [ + models.CheckConstraint( + check=models.Q(end_date__isnull=True) + | models.Q(end_date__gte=models.F("start_date")), + name="chk_cycles_date_range", + ), + models.UniqueConstraint( + fields=["city_site", "source_cycle_id"], + condition=models.Q(city_site__isnull=False, source_cycle_id__isnull=False), + name="uniq_cycle_city_source", + ), + ] + + def __str__(self) -> str: + return f"Cycle #{self.pk} ({self.status})" + + def clean(self) -> None: + if self.end_date and self.start_date and self.end_date < self.start_date: + raise ValidationError({"end_date": "Must be on or after start_date"}) + if ( + self.proposed_end_date + and self.start_date + and self.proposed_end_date < self.start_date + ): + raise ValidationError( + {"proposed_end_date": "Must be on or after start_date"} + ) + + def soft_end_date(self) -> date: + if self.end_date: + return self.end_date + from apps.operations.services.visibility import visible_through_date + + return visible_through_date() + + def resolved_status(self) -> str: + return self.status + + def sync_status(self) -> bool: + return False + + def save(self, *args, **kwargs): + self.sync_status() + if kwargs.get("update_fields") is None: + if self.end_date and self.start_date: + self.total_days = max((self.end_date - self.start_date).days + 1, 1) + elif self.start_date and not self.end_date: + soft = self.soft_end_date() + self.total_days = max((soft - self.start_date).days + 1, 1) + super().save(*args, **kwargs) + + def clear_close_request_fields(self) -> None: + self.proposed_end_date = None + self.close_requested_at = None + self.close_requested_by = None + + def mark_pending_close(self, proposed_end_date: date, requested_at=None) -> None: + if proposed_end_date < self.start_date: + raise ValidationError( + {"proposed_end_date": "Must be on or after start_date"} + ) + self.status = self.STATUS_PENDING_CLOSE + self.proposed_end_date = proposed_end_date + self.close_requested_at = requested_at or timezone.now() + self.close_approved_by = None + self.close_approved_at = None + self.save( + update_fields=[ + "status", + "proposed_end_date", + "close_requested_at", + "close_approved_by", + "close_approved_at", + "updated_at", + ] + ) + + def cancel_pending_close(self) -> None: + if self.status == self.STATUS_ACTIVE and self.proposed_end_date is None: + return + if self.status == self.STATUS_CLOSED: + raise ValidationError("Cycle is already closed.") + self.status = self.STATUS_ACTIVE + self.clear_close_request_fields() + self.save( + update_fields=[ + "status", + "proposed_end_date", + "close_requested_at", + "close_requested_by", + "updated_at", + ] + ) + + def approve_close(self, approver: User) -> None: + if self.status != self.STATUS_PENDING_CLOSE: + raise ValidationError("Cycle is not pending close approval.") + if not self.proposed_end_date: + raise ValidationError("proposed_end_date is missing.") + self.status = self.STATUS_CLOSED + self.end_date = self.proposed_end_date + self.total_days = max((self.end_date - self.start_date).days + 1, 1) + self.close_approved_by = approver + self.close_approved_at = timezone.now() + self.clear_close_request_fields() + self.save( + update_fields=[ + "status", + "end_date", + "total_days", + "close_approved_by", + "close_approved_at", + "proposed_end_date", + "close_requested_at", + "close_requested_by", + "updated_at", + ] + ) + + def reject_close(self, _actor: User) -> None: + if self.status != self.STATUS_PENDING_CLOSE: + raise ValidationError("Cycle is not pending close approval.") + self.status = self.STATUS_ACTIVE + self.clear_close_request_fields() + self.save( + update_fields=[ + "status", + "proposed_end_date", + "close_requested_at", + "close_requested_by", + "updated_at", + ] + ) + + @property + def current_day(self) -> int: + from apps.operations.services.visibility import visible_through_date + + effective = visible_through_date() + if effective < self.start_date: + return 0 + elapsed = (effective - self.start_date).days + if self.end_date: + max_day = max(self.total_days - 1, 0) + return min(max(elapsed, 0), max_day) + return max(elapsed, 0) + + @property + def visible_through_date(self) -> date: + from apps.operations.services.visibility import visible_through_date as cutoff_date + + return cutoff_date() diff --git a/backend/apps/farms/serializers.py b/backend/apps/farms/serializers.py new file mode 100644 index 0000000..8e8b1cd --- /dev/null +++ b/backend/apps/farms/serializers.py @@ -0,0 +1,152 @@ +from rest_framework import serializers + +from apps.accounts.serializers import PkAsIdMixin +from apps.farms.models import Cycle, Flock, Kandang, Site + + +class SiteSerializer(PkAsIdMixin, serializers.ModelSerializer): + owner_name = serializers.CharField(source="user.user_name", read_only=True) + + class Meta: + model = Site + fields = [ + "id", + "site_name", + "user", + "owner_name", + "city_site", + "created_at", + "updated_at", + ] + read_only_fields = ["id", "owner_name", "city_site", "created_at", "updated_at"] + + +class FeedInButtonUrlSerializer(serializers.Serializer): + label = serializers.CharField(max_length=50, required=False, allow_blank=True, default="") + url = serializers.URLField(max_length=500) + + +class KandangSerializer(PkAsIdMixin, serializers.ModelSerializer): + feed_in_button_urls = FeedInButtonUrlSerializer(many=True, required=False) + + class Meta: + model = Kandang + fields = [ + "id", + "kandang_name", + "feed_in_button_urls", + "site", + "created_at", + "updated_at", + ] + read_only_fields = ["id", "created_at", "updated_at"] + + def validate_feed_in_button_urls(self, value): + cleaned = [] + for item in value or []: + url = str(item.get("url", "")).strip() + if not url: + continue + label = str(item.get("label", "") or "").strip()[:50] + cleaned.append({"label": label, "url": url}) + return cleaned + + def update(self, instance, validated_data): + urls = validated_data.pop("feed_in_button_urls", None) + instance = super().update(instance, validated_data) + if urls is not None: + instance.feed_in_button_urls = urls + instance.save(update_fields=["feed_in_button_urls", "updated_at"]) + return instance + + def to_representation(self, instance): + data = super().to_representation(instance) + urls = data.get("feed_in_button_urls") or [] + if not isinstance(urls, list): + urls = [] + data["feed_in_button_urls"] = [ + {"label": str(item.get("label", "") or ""), "url": str(item.get("url", "") or "")} + for item in urls + if isinstance(item, dict) and str(item.get("url", "") or "").strip() + ] + return data + + +class FlockSerializer(PkAsIdMixin, serializers.ModelSerializer): + class Meta: + model = Flock + fields = ["id", "flock_name", "kandang", "created_at", "updated_at"] + read_only_fields = ["id", "created_at", "updated_at"] + + +class CycleSerializer(PkAsIdMixin, serializers.ModelSerializer): + kandang = serializers.PrimaryKeyRelatedField(queryset=Kandang.objects.all()) + kandang_name = serializers.CharField(source="kandang.kandang_name", read_only=True) + chick_in_weight = serializers.IntegerField(source="doc_in_weight") + current_day = serializers.IntegerField(read_only=True) + visible_through_date = serializers.DateField(read_only=True) + soft_end_date = serializers.SerializerMethodField() + + class Meta: + model = Cycle + fields = [ + "id", + "kandang", + "kandang_name", + "total_days", + "current_day", + "visible_through_date", + "soft_end_date", + "start_date", + "end_date", + "chick_in_weight", + "doc_in_count", + "feed_initial_balance", + "feed_initial_balance_date", + "status", + "city_site", + "source_cycle_id", + "proposed_end_date", + "close_requested_at", + "close_requested_by", + "close_approved_by", + "close_approved_at", + "created_at", + "updated_at", + ] + read_only_fields = [ + "id", + "kandang_name", + "feed_initial_balance", + "feed_initial_balance_date", + "status", + "city_site", + "source_cycle_id", + "proposed_end_date", + "close_requested_at", + "close_requested_by", + "close_approved_by", + "close_approved_at", + "created_at", + "updated_at", + "soft_end_date", + ] + + def get_soft_end_date(self, obj: Cycle): + return obj.soft_end_date() + + def validate(self, attrs): + attrs.pop("status", None) + if self.instance is None: + attrs.pop("end_date", None) + attrs.setdefault("total_days", 1) + else: + attrs.pop("end_date", None) + start = attrs.get("start_date", getattr(self.instance, "start_date", None)) + end = attrs.get("end_date", getattr(self.instance, "end_date", None)) + if start and end and end < start: + raise serializers.ValidationError({"end_date": "Must be on or after start_date."}) + return attrs + + def to_representation(self, instance): + return super().to_representation(instance) diff --git a/backend/apps/farms/services/__init__.py b/backend/apps/farms/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/farms/services/city_registry.py b/backend/apps/farms/services/city_registry.py new file mode 100644 index 0000000..ab8713f --- /dev/null +++ b/backend/apps/farms/services/city_registry.py @@ -0,0 +1,43 @@ +"""Link HQ Site rows to CitySite registry entries (Pengaturan view list).""" + +from __future__ import annotations + +from apps.farms.models import Site +from apps.sync.models import CitySite + + +def ensure_hq_site_for_city(city: CitySite) -> Site: + """ + Ensure the city registry entry has an HQ Site for farm visibility. + + Prefers an existing linked site, then an unlinked site owned by the + registrar with a matching name (so seeded Sukawarna attaches when + registered), otherwise creates a new Site. + """ + existing = Site.objects.filter(city_site=city).first() + if existing: + return existing + + owner = city.registered_by + if owner is None: + raise ValueError("CitySite.registered_by is required to create an HQ site.") + + site_name = (city.name or city.code or "Site")[:30] + orphan = ( + Site.objects.filter(user=owner, city_site__isnull=True, site_name__iexact=site_name) + .order_by("pk") + .first() + ) + if orphan is None and city.code: + # e.g. code "sukawarna" ↔ site_name "Sukawarna" + orphan = ( + Site.objects.filter(user=owner, city_site__isnull=True, site_name__iexact=city.code) + .order_by("pk") + .first() + ) + if orphan is not None: + orphan.city_site = city + orphan.save(update_fields=["city_site", "updated_at"]) + return orphan + + return Site.objects.create(site_name=site_name, user=owner, city_site=city) diff --git a/backend/apps/farms/services/site_close.py b/backend/apps/farms/services/site_close.py new file mode 100644 index 0000000..ff0dcd9 --- /dev/null +++ b/backend/apps/farms/services/site_close.py @@ -0,0 +1,49 @@ +"""Push close decisions from pusat to city dashboard-cpsp.""" + +from __future__ import annotations + +import logging + +import requests + +from apps.farms.models import Cycle + +logger = logging.getLogger(__name__) + + +class SiteClosePushError(Exception): + def __init__(self, message: str): + self.message = message + super().__init__(message) + + +def push_close_decision(cycle: Cycle, *, approved: bool) -> None: + city = cycle.city_site + if not city or not city.api_base_url or not city.api_key or not cycle.source_cycle_id: + logger.info("No city channel configured for cycle %s; skip push", cycle.pk) + return + + base = city.api_base_url.rstrip("/") + url = f"{base}/cycles/{cycle.source_cycle_id}/apply-close-decision/" + payload = {"decision": "approve" if approved else "reject"} + if approved: + if not cycle.end_date: + raise SiteClosePushError("Approved cycle is missing end_date.") + payload["end_date"] = cycle.end_date.isoformat() + + try: + response = requests.post( + url, + json=payload, + headers={"X-API-Key": city.api_key, "Content-Type": "application/json"}, + timeout=30, + ) + if response.status_code >= 400: + raise SiteClosePushError( + f"Gagal kirim keputusan ke situs ({response.status_code}: {response.text[:200]})" + ) + except SiteClosePushError: + raise + except requests.RequestException as exc: + logger.exception("Push close decision failed for cycle %s", cycle.pk) + raise SiteClosePushError("Gagal kirim keputusan ke situs — coba lagi") from exc diff --git a/backend/apps/farms/tests.py b/backend/apps/farms/tests.py new file mode 100644 index 0000000..c8b956b --- /dev/null +++ b/backend/apps/farms/tests.py @@ -0,0 +1,394 @@ +from datetime import date, timedelta +from unittest.mock import patch + +from django.test import TestCase +from rest_framework.test import APIClient + +from apps.accounts.models import User +from apps.farms.models import Cycle, Flock, Kandang, Site +from apps.operations.models import FeedSacks, ManualInput + + +class FarmAPITests(TestCase): + def setUp(self): + self.user = User.objects.create_user(user_name="tester", password="secret") + self.admin = User.objects.create_user( + user_name="admin", + password="secret", + status=User.STATUS_DIRECTOR_ADMIN, + ) + self.client = APIClient() + self.site = Site.objects.create(site_name="Sukawarna", user=self.user) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=self.site) + + def test_create_flock_under_kandang_requires_director_admin(self): + self.client.force_authenticate(self.admin) + response = self.client.post( + "/api/v1/flocks/", + {"flock_name": "Lantai 1", "kandang": self.kandang.pk}, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + self.assertEqual(response.data["flock_name"], "Lantai 1") + self.assertEqual(response.data["kandang"], self.kandang.pk) + + def test_staff_cannot_create_flock(self): + self.client.force_authenticate(self.user) + response = self.client.post( + "/api/v1/flocks/", + {"flock_name": "Lantai 1", "kandang": self.kandang.pk}, + format="json", + ) + self.assertEqual(response.status_code, 403, response.data) + + def test_create_cycle_without_flock(self): + self.client.force_authenticate(self.user) + start = date.today() + response = self.client.post( + "/api/v1/cycles/", + { + "kandang": self.kandang.pk, + "total_days": 35, + "start_date": start.isoformat(), + "end_date": (start + timedelta(days=34)).isoformat(), + "chick_in_weight": 42, + "doc_in_count": 10000, + "status": "active", + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + self.assertNotIn("flock", response.data) + self.assertNotIn("flock_name", response.data) + + def test_update_cycle(self): + self.client.force_authenticate(self.user) + start = date(2026, 8, 1) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + new_end = start + timedelta(days=39) + response = self.client.patch( + f"/api/v1/cycles/{cycle.pk}/", + { + "end_date": new_end.isoformat(), + "total_days": 40, + "doc_in_count": 9500, + "chick_in_weight": 42, + }, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + cycle.refresh_from_db() + self.assertEqual(cycle.end_date, new_end) + self.assertEqual(cycle.total_days, 40) + self.assertEqual(cycle.doc_in_count, 9500) + self.assertEqual(cycle.doc_in_weight, 42) + + def test_cycle_stays_active_without_gm_approval(self): + """HQ does not auto-close by publish cutoff — GM approve-close is required.""" + self.client.force_authenticate(self.user) + start = date(2026, 8, 1) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=None, + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + + response = self.client.get(f"/api/v1/cycles/{cycle.pk}/") + + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["status"], Cycle.STATUS_ACTIVE) + cycle.refresh_from_db() + self.assertEqual(cycle.status, Cycle.STATUS_ACTIVE) + + def test_gm_can_approve_cycle_close(self): + gm = User.objects.create_user(user_name="gm_approver", password="x", status=User.STATUS_GM) + site = Site.objects.create(site_name="GM Site", user=gm) + kandang = Kandang.objects.create(kandang_name="Kandang GM", site=site) + self.client.force_authenticate(gm) + start = date(2026, 8, 1) + proposed = start + timedelta(days=34) + cycle = Cycle.objects.create( + kandang=kandang, + total_days=1, + start_date=start, + end_date=None, + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_PENDING_CLOSE, + proposed_end_date=proposed, + ) + + response = self.client.post(f"/api/v1/cycles/{cycle.pk}/approve-close/") + + self.assertEqual(response.status_code, 200, response.data) + body = response.data.get("cycle", response.data) + self.assertEqual(body["status"], Cycle.STATUS_CLOSED) + self.assertEqual(body["end_date"], proposed.isoformat()) + cycle.refresh_from_db() + self.assertEqual(cycle.status, Cycle.STATUS_CLOSED) + self.assertEqual(cycle.close_approved_by_id, gm.pk) + self.assertIsNotNone(cycle.close_approved_at) + self.assertEqual(cycle.end_date, proposed) + + def test_gm_can_reject_cycle_close(self): + gm = User.objects.create_user(user_name="gm_rejector", password="x", status=User.STATUS_GM) + site = Site.objects.create(site_name="GM Reject Site", user=gm) + kandang = Kandang.objects.create(kandang_name="Kandang R", site=site) + self.client.force_authenticate(gm) + start = date(2026, 8, 1) + cycle = Cycle.objects.create( + kandang=kandang, + total_days=1, + start_date=start, + end_date=None, + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_PENDING_CLOSE, + proposed_end_date=start + timedelta(days=20), + ) + + response = self.client.post(f"/api/v1/cycles/{cycle.pk}/reject-close/") + + self.assertEqual(response.status_code, 200, response.data) + body = response.data.get("cycle", response.data) + self.assertEqual(body["status"], Cycle.STATUS_ACTIVE) + cycle.refresh_from_db() + self.assertEqual(cycle.status, Cycle.STATUS_ACTIVE) + self.assertIsNone(cycle.proposed_end_date) + + def test_gm_admin_cannot_approve_cycle_close(self): + gm_admin = User.objects.create_user( + user_name="gm_admin_user", password="x", status=User.STATUS_GM_ADMIN + ) + site = Site.objects.create(site_name="GM Admin Site", user=gm_admin) + kandang = Kandang.objects.create(kandang_name="Kandang GMA", site=site) + self.client.force_authenticate(gm_admin) + start = date(2026, 8, 1) + cycle = Cycle.objects.create( + kandang=kandang, + total_days=1, + start_date=start, + end_date=None, + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_PENDING_CLOSE, + proposed_end_date=start + timedelta(days=34), + ) + + response = self.client.post(f"/api/v1/cycles/{cycle.pk}/approve-close/") + + self.assertEqual(response.status_code, 403) + cycle.refresh_from_db() + self.assertEqual(cycle.status, Cycle.STATUS_PENDING_CLOSE) + + def test_flock_persists_across_cycles(self): + flock = Flock.objects.create(flock_name="Lantai 1", kandang=self.kandang) + start = date.today() + for offset in (0, 40): + Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start + timedelta(days=offset), + end_date=start + timedelta(days=offset + 34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + self.assertEqual(Flock.objects.filter(kandang=self.kandang).count(), 1) + self.assertEqual(flock.kandang_id, self.kandang.pk) + + def test_current_day_is_zero_based_from_start_date(self): + start = date(2026, 9, 2) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + + with patch( + "apps.operations.services.visibility.visible_through_date", + return_value=start, + ): + self.assertEqual(cycle.current_day, 0) + + with patch( + "apps.operations.services.visibility.visible_through_date", + return_value=start + timedelta(days=1), + ): + self.assertEqual(cycle.current_day, 1) + + def test_list_flocks_by_kandang(self): + self.client.force_authenticate(self.user) + Flock.objects.create(flock_name="Lantai 1", kandang=self.kandang) + Flock.objects.create(flock_name="Lantai 2", kandang=self.kandang) + other_kandang = Kandang.objects.create(kandang_name="Kandang 2", site=self.site) + Flock.objects.create(flock_name="Other", kandang=other_kandang) + response = self.client.get("/api/v1/flocks/", {"kandang_id": self.kandang.pk}) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(len(results), 2) + + def test_set_initial_balance_does_not_create_feed_sack_row(self): + start = date.today() + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + + self.client.force_authenticate(self.user) + response = self.client.post( + f"/api/v1/cycles/{cycle.pk}/initial-balance/", + {"date": start.isoformat(), "feed_in_manual": 120}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["feed_initial_balance_date"], start.isoformat()) + cycle.refresh_from_db() + self.assertEqual(cycle.feed_initial_balance, 120) + self.assertFalse(FeedSacks.objects.filter(cycle=cycle).exists()) + self.assertFalse(ManualInput.objects.filter(cycle=cycle).exists()) + + def test_set_initial_balance_does_not_change_existing_feed_sack_totals(self): + start = date.today() + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + feed_row = FeedSacks.objects.create( + cycle=cycle, + date=start + timedelta(days=1), + in_today=4, + in_total=4, + out_today=0, + out_total=0, + feed_use_today=0, + feed_use_total=0, + ) + + self.client.force_authenticate(self.user) + response = self.client.post( + f"/api/v1/cycles/{cycle.pk}/initial-balance/", + {"date": start.isoformat(), "feed_in_manual": 120}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + + feed_row.refresh_from_db() + self.assertEqual(feed_row.in_total, 4) + + def test_set_initial_balance_twice_on_different_dates_keeps_daily_totals(self): + start = date(2026, 8, 26) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + feed_row = FeedSacks.objects.create( + cycle=cycle, + date=start + timedelta(days=2), + in_today=6, + in_total=6, + out_today=0, + out_total=0, + feed_use_today=0, + feed_use_total=0, + ) + + self.client.force_authenticate(self.user) + first = self.client.post( + f"/api/v1/cycles/{cycle.pk}/initial-balance/", + {"date": start.isoformat(), "feed_in_manual": 120}, + format="json", + ) + self.assertEqual(first.status_code, 200, first.data) + second = self.client.post( + f"/api/v1/cycles/{cycle.pk}/initial-balance/", + {"date": (start + timedelta(days=1)).isoformat(), "feed_in_manual": 80}, + format="json", + ) + self.assertEqual(second.status_code, 200, second.data) + + cycle.refresh_from_db() + self.assertEqual(cycle.feed_initial_balance, 80) + self.assertEqual(cycle.feed_initial_balance_date, start + timedelta(days=1)) + self.assertEqual(FeedSacks.objects.filter(cycle=cycle).count(), 1) + feed_row.refresh_from_db() + self.assertEqual(feed_row.in_total, 6) + + @patch("apps.farms.views.pull_initial_balance_iot", return_value=(115, None)) + def test_set_initial_balance_compares_manual_against_combined_api_iot(self, mock_pull): + start = date(2026, 8, 26) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + status=Cycle.STATUS_ACTIVE, + ) + + self.client.force_authenticate(self.user) + response = self.client.post( + f"/api/v1/cycles/{cycle.pk}/initial-balance/", + {"date": start.isoformat(), "feed_in_manual": 120}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["iot"], 115) + self.assertEqual(response.data["accuracy"], 95.8) + mock_pull.assert_called_once_with(cycle, start) + + @patch("apps.farms.views.pull_initial_balance_iot", return_value=(112, None)) + def test_compare_initial_balance_returns_iot_and_accuracy(self, mock_pull): + start = date(2026, 8, 27) + cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=start, + end_date=start + timedelta(days=34), + doc_in_weight=40, + doc_in_count=9000, + feed_initial_balance=120, + status=Cycle.STATUS_ACTIVE, + ) + + self.client.force_authenticate(self.user) + response = self.client.get( + f"/api/v1/cycles/{cycle.pk}/initial-balance-compare/", + {"date": start.isoformat(), "manual": 120}, + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["iot"], 112) + self.assertEqual(response.data["accuracy"], 93.3) + mock_pull.assert_called_once_with(cycle, start) diff --git a/backend/apps/farms/tests_feed_in_button.py b/backend/apps/farms/tests_feed_in_button.py new file mode 100644 index 0000000..6965d95 --- /dev/null +++ b/backend/apps/farms/tests_feed_in_button.py @@ -0,0 +1,75 @@ +from django.test import Client, TestCase + +from apps.accounts.models import User +from apps.farms.models import Kandang, Site + + +class KandangFeedInButtonUrlTests(TestCase): + def setUp(self): + self.owner = User.objects.create_user(user_name="owner", password="secret") + self.admin = User.objects.create_user( + user_name="admin", + password="admin123", + status=User.STATUS_DIRECTOR_ADMIN, + ) + self.staff = User.objects.create_user( + user_name="staff", + password="staff123", + status=User.STATUS_GM, + ) + self.site = Site.objects.create(site_name="Site A", user=self.owner) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=self.site) + self.payload = { + "feed_in_button_urls": [{"label": "Gudang A", "url": "http://192.168.1.10:8080/"}] + } + + def _csrf_headers(self, client: Client) -> dict[str, str]: + token = client.cookies["csrftoken"].value + return {"HTTP_X_CSRFTOKEN": token} + + def _login(self, client: Client, user_name: str, password: str) -> None: + client.get("/api/v1/auth/csrf/") + response = client.post( + "/api/v1/auth/login/", + {"user_name": user_name, "password": password}, + content_type="application/json", + **self._csrf_headers(client), + ) + self.assertEqual(response.status_code, 200, response.content) + + def test_director_admin_can_save_feed_in_button_urls(self): + client = Client(enforce_csrf_checks=True) + self._login(client, "admin", "admin123") + response = client.patch( + f"/api/v1/kandangs/{self.kandang.pk}/", + self.payload, + content_type="application/json", + **self._csrf_headers(client), + ) + self.assertEqual(response.status_code, 200, response.content) + self.kandang.refresh_from_db() + self.assertEqual(self.kandang.feed_in_button_urls, self.payload["feed_in_button_urls"]) + + def test_staff_cannot_save_feed_in_button_urls(self): + client = Client(enforce_csrf_checks=True) + self._login(client, "staff", "staff123") + response = client.patch( + f"/api/v1/kandangs/{self.kandang.pk}/", + self.payload, + content_type="application/json", + **self._csrf_headers(client), + ) + self.assertEqual(response.status_code, 403, response.content) + self.kandang.refresh_from_db() + self.assertEqual(self.kandang.feed_in_button_urls, []) + + def test_staff_cannot_rename_kandang(self): + client = Client(enforce_csrf_checks=True) + self._login(client, "staff", "staff123") + response = client.patch( + f"/api/v1/kandangs/{self.kandang.pk}/", + {"kandang_name": "Renamed"}, + content_type="application/json", + **self._csrf_headers(client), + ) + self.assertEqual(response.status_code, 403, response.content) diff --git a/backend/apps/farms/urls.py b/backend/apps/farms/urls.py new file mode 100644 index 0000000..dc68e7b --- /dev/null +++ b/backend/apps/farms/urls.py @@ -0,0 +1,22 @@ +from django.urls import path +from rest_framework.routers import DefaultRouter + +from apps.farms.views import ( + CycleViewSet, + FlockViewSet, + KandangViewSet, + SiteViewSet, + cycle_close_cancel, + cycle_close_ingest, +) + +router = DefaultRouter() +router.register("sites", SiteViewSet, basename="site") +router.register("kandangs", KandangViewSet, basename="kandang") +router.register("flocks", FlockViewSet, basename="flock") +router.register("cycles", CycleViewSet, basename="cycle") + +urlpatterns = [ + path("cycle-close/ingest/", cycle_close_ingest, name="cycle-close-ingest"), + path("cycle-close/cancel/", cycle_close_cancel, name="cycle-close-cancel"), +] + router.urls diff --git a/backend/apps/farms/views.py b/backend/apps/farms/views.py new file mode 100644 index 0000000..e9e8553 --- /dev/null +++ b/backend/apps/farms/views.py @@ -0,0 +1,382 @@ +from django.core.exceptions import ValidationError +from django.utils.dateparse import parse_date, parse_datetime +from rest_framework import permissions, status, viewsets +from rest_framework.decorators import action, api_view, permission_classes +from rest_framework.response import Response + +from apps.accounts.models import User +from apps.accounts.permissions import CanApproveCycleClose, can_approve_cycle_close +from apps.accounts.scoping import ( + filter_cycles_queryset, + filter_flocks_queryset, + filter_kandangs_queryset, + filter_sites_queryset, +) +from apps.farms.models import Cycle, Flock, Kandang, Site +from apps.farms.serializers import CycleSerializer, FlockSerializer, KandangSerializer, SiteSerializer +from apps.farms.services.site_close import SiteClosePushError, push_close_decision +from apps.operations.services.feed_sacks import ( + cleanup_opening_balance_feed_rows, + recompute_feed_sack_in_totals, +) +from apps.operations.services.karung_web import ( + initial_balance_accuracy, + pull_initial_balance_iot, +) +from apps.farms.services.city_registry import ensure_hq_site_for_city +from apps.sync.models import CitySite + + +def _validation_detail(exc: ValidationError): + if hasattr(exc, "message_dict"): + return exc.message_dict + if hasattr(exc, "messages"): + return "; ".join(str(m) for m in exc.messages) + return str(getattr(exc, "message", exc)) + + +def _upsert_mirror_cycle_from_ingest(city: CitySite, payload: dict) -> Cycle: + source_cycle_id = payload.get("source_cycle_id") + if not source_cycle_id: + raise ValidationError("source_cycle_id is required.") + proposed = parse_date(str(payload.get("proposed_end_date") or "")) + if proposed is None: + raise ValidationError("proposed_end_date is required.") + start = parse_date(str(payload.get("start_date") or "")) + if start is None: + raise ValidationError("start_date is required.") + + site_name = str(payload.get("site_name") or city.name)[:30] + kandang_name = str(payload.get("kandang_name") or "Kandang")[:30] + owner = city.registered_by + if owner is None: + owner = User.objects.filter(status=User.STATUS_GM).first() + if owner is None: + raise ValidationError("No GM available to own mirrored site.") + + site = ensure_hq_site_for_city(city) + if site.site_name != site_name and not Site.objects.filter( + user=owner, site_name=site_name + ).exclude(pk=site.pk).exists(): + # Prefer ingest site_name when it does not collide. + site.site_name = site_name + site.save(update_fields=["site_name", "updated_at"]) + kandang, _ = Kandang.objects.get_or_create( + site=site, + kandang_name=kandang_name, + defaults={}, + ) + + cycle = Cycle.objects.filter(city_site=city, source_cycle_id=source_cycle_id).first() + if cycle is None: + cycle = Cycle( + kandang=kandang, + city_site=city, + source_cycle_id=source_cycle_id, + start_date=start, + end_date=None, + doc_in_weight=int(payload.get("doc_in_weight") or 0), + doc_in_count=int(payload.get("doc_in_count") or 0), + total_days=int(payload.get("total_days") or 1), + status=Cycle.STATUS_ACTIVE, + ) + cycle.save() + else: + cycle.kandang = kandang + cycle.start_date = start + cycle.doc_in_weight = int(payload.get("doc_in_weight") or cycle.doc_in_weight) + cycle.doc_in_count = int(payload.get("doc_in_count") or cycle.doc_in_count) + cycle.save() + + requested_dt = parse_datetime(str(payload.get("requested_at") or "")) or None + cycle.mark_pending_close(proposed, requested_at=requested_dt) + return cycle + + +@api_view(["POST"]) +@permission_classes([permissions.IsAuthenticated]) +def cycle_close_ingest(request): + """Site → pusat: register/update a pending close request.""" + city_site_id = request.data.get("city_site_id") + try: + city = CitySite.objects.get(pk=city_site_id, is_active=True) + except (CitySite.DoesNotExist, TypeError, ValueError): + return Response({"detail": "Invalid city_site_id."}, status=status.HTTP_400_BAD_REQUEST) + try: + cycle = _upsert_mirror_cycle_from_ingest(city, request.data) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + return Response(CycleSerializer(cycle).data) + + +@api_view(["POST"]) +@permission_classes([permissions.IsAuthenticated]) +def cycle_close_cancel(request): + """Site → pusat: cancel a pending close request.""" + city_site_id = request.data.get("city_site_id") + source_cycle_id = request.data.get("source_cycle_id") + try: + city = CitySite.objects.get(pk=city_site_id, is_active=True) + except (CitySite.DoesNotExist, TypeError, ValueError): + return Response({"detail": "Invalid city_site_id."}, status=status.HTTP_400_BAD_REQUEST) + cycle = Cycle.objects.filter(city_site=city, source_cycle_id=source_cycle_id).first() + if cycle is None: + return Response({"detail": "Mirror cycle not found."}, status=status.HTTP_404_NOT_FOUND) + try: + cycle.cancel_pending_close() + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + return Response(CycleSerializer(cycle).data) + + +class IsDirectorAdminForWrite(permissions.BasePermission): + """Reads for any authenticated executive; structure writes for director_admin. + + Mirrored farm structures should normally arrive via city sync. Manual + create/edit/delete is reserved for director_admin (bootstrap / repair). + """ + + def has_permission(self, request, view): + if not request.user or not request.user.is_authenticated: + return False + if request.method in permissions.SAFE_METHODS: + return True + return bool( + request.user.is_superuser + or getattr(request.user, "status", None) + in { + User.STATUS_DIRECTOR_ADMIN, + User.STATUS_SUPERUSER, + } + ) + + +class SiteViewSet(viewsets.ModelViewSet): + queryset = Site.objects.select_related("user").all() + serializer_class = SiteSerializer + permission_classes = [IsDirectorAdminForWrite] + + def get_queryset(self): + qs = filter_sites_queryset(super().get_queryset(), self.request.user) + user_id = self.request.query_params.get("user_id") + if user_id: + qs = qs.filter(user_id=user_id) + return qs + + +class KandangViewSet(viewsets.ModelViewSet): + queryset = Kandang.objects.select_related("site").all() + serializer_class = KandangSerializer + permission_classes = [IsDirectorAdminForWrite] + + def get_queryset(self): + qs = filter_kandangs_queryset(super().get_queryset(), self.request.user) + site_id = self.request.query_params.get("site_id") + if site_id: + qs = qs.filter(site_id=site_id) + return qs + + +class FlockViewSet(viewsets.ModelViewSet): + queryset = Flock.objects.select_related("kandang").all() + serializer_class = FlockSerializer + permission_classes = [IsDirectorAdminForWrite] + + def get_queryset(self): + qs = filter_flocks_queryset(super().get_queryset(), self.request.user) + kandang_id = self.request.query_params.get("kandang_id") + if kandang_id: + qs = qs.filter(kandang_id=kandang_id) + return qs + + +class CycleViewSet(viewsets.ModelViewSet): + queryset = Cycle.objects.select_related( + "kandang", "close_approved_by", "city_site", "kandang__site" + ).all() + serializer_class = CycleSerializer + + def get_queryset(self): + qs = filter_cycles_queryset(super().get_queryset(), self.request.user) + params = self.request.query_params + if params.get("kandang_id"): + qs = qs.filter(kandang_id=params["kandang_id"]) + if params.get("status"): + qs = qs.filter(status=params["status"]) + return qs + + @action( + detail=True, + methods=["post"], + url_path="approve-close", + permission_classes=[CanApproveCycleClose], + ) + def approve_close(self, request, pk=None): + """GM-only: approve closing a cycle on the pusat mirror.""" + if not can_approve_cycle_close(request.user): + return Response({"detail": "Only GM may approve cycle close."}, status=status.HTTP_403_FORBIDDEN) + cycle = self.get_object() + try: + cycle.approve_close(request.user) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + + site_error = None + try: + push_close_decision(cycle, approved=True) + except SiteClosePushError as exc: + site_error = exc.message + + data = CycleSerializer(cycle).data + if site_error: + return Response({"cycle": data, "site_error": site_error}) + return Response(data) + + @action( + detail=True, + methods=["post"], + url_path="reject-close", + permission_classes=[CanApproveCycleClose], + ) + def reject_close(self, request, pk=None): + """GM-only: reject a pending close request.""" + if not can_approve_cycle_close(request.user): + return Response({"detail": "Only GM may reject cycle close."}, status=status.HTTP_403_FORBIDDEN) + cycle = self.get_object() + try: + cycle.reject_close(request.user) + except ValidationError as exc: + return Response({"detail": _validation_detail(exc)}, status=status.HTTP_400_BAD_REQUEST) + + site_error = None + try: + push_close_decision(cycle, approved=False) + except SiteClosePushError as exc: + site_error = exc.message + + data = CycleSerializer(cycle).data + if site_error: + return Response({"cycle": data, "site_error": site_error}) + return Response(data) + + @action(detail=True, methods=["get"], url_path="initial-balance-compare") + def compare_initial_balance(self, request, pk=None): + """Pull IoT masuk for a date and compare against the cycle saldo awal.""" + cycle = self.get_object() + + date_str = request.query_params.get("date") + if not date_str: + return Response({"detail": "date is required."}, status=status.HTTP_400_BAD_REQUEST) + balance_date = parse_date(str(date_str)) + if balance_date is None: + return Response( + {"detail": "date must be in YYYY-MM-DD format."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + manual_raw = request.query_params.get("manual") + if manual_raw is None: + feed_in_manual = cycle.feed_initial_balance + else: + try: + feed_in_manual = int(manual_raw) + except (TypeError, ValueError): + return Response( + {"detail": "manual must be an integer."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + iot_in, sync_error = pull_initial_balance_iot(cycle, balance_date) + return Response( + { + "cycle": cycle.pk, + "date": balance_date.isoformat(), + "feed_initial_balance": cycle.feed_initial_balance, + "feed_initial_balance_date": ( + cycle.feed_initial_balance_date.isoformat() + if cycle.feed_initial_balance_date + else None + ), + "manual": feed_in_manual, + "manual_total": feed_in_manual, + "iot": iot_in, + "accuracy": initial_balance_accuracy(feed_in_manual, iot_in), + "sync_error": sync_error, + } + ) + + @action(detail=True, methods=["post"], url_path="initial-balance") + def set_initial_balance(self, request, pk=None): + """Save the feed-in balance for the cycle (Saldo Awal). + + Sets ``feed_initial_balance`` on the cycle (the only cycle field this + feature writes — never during cycle creation). Opening balance is kept on + the cycle for saldo only and is not written into daily FeedSacks rows. + Pulls the IoT-detected "in" for that date from karung-web-admin + ``/api/combined`` and returns a manual vs IoT accuracy figure. + """ + cycle = self.get_object() + + date_str = request.data.get("date") + if not date_str: + return Response({"detail": "date is required."}, status=status.HTTP_400_BAD_REQUEST) + balance_date = parse_date(str(date_str)) + if balance_date is None: + return Response( + {"detail": "date must be in YYYY-MM-DD format."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + feed_in_manual = int(request.data.get("feed_in_manual")) + except (TypeError, ValueError): + return Response( + {"detail": "feed_in_manual must be an integer."}, + status=status.HTTP_400_BAD_REQUEST, + ) + if feed_in_manual < 0: + return Response( + {"detail": "feed_in_manual cannot be negative."}, + status=status.HTTP_400_BAD_REQUEST, + ) + + previous_date = cycle.feed_initial_balance_date + previous_balance = cycle.feed_initial_balance + + cycle.feed_initial_balance = feed_in_manual + cycle.feed_initial_balance_date = balance_date + cycle.save( + update_fields=["feed_initial_balance", "feed_initial_balance_date", "updated_at"] + ) + + # Pull IoT "in" at the balance date from karung-web-admin /api/combined. + iot_in, sync_error = pull_initial_balance_iot(cycle, balance_date) + + cleanup_opening_balance_feed_rows( + cycle, + previous_date=previous_date, + previous_balance=previous_balance, + balance_date=balance_date, + balance_amount=feed_in_manual, + ) + recompute_feed_sack_in_totals(cycle) + + accuracy = initial_balance_accuracy(feed_in_manual, iot_in) + + return Response( + { + "cycle": cycle.pk, + "date": balance_date.isoformat(), + "feed_initial_balance": cycle.feed_initial_balance, + "feed_initial_balance_date": ( + cycle.feed_initial_balance_date.isoformat() + if cycle.feed_initial_balance_date + else None + ), + "manual": feed_in_manual, + "manual_total": feed_in_manual, + "iot": iot_in, + "accuracy": accuracy, + "sync_error": sync_error, + } + ) diff --git a/backend/apps/jobs/__init__.py b/backend/apps/jobs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/jobs/apps.py b/backend/apps/jobs/apps.py new file mode 100644 index 0000000..66f9c20 --- /dev/null +++ b/backend/apps/jobs/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class JobsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.jobs" + label = "jobs" + verbose_name = "Jobs" diff --git a/backend/apps/jobs/management/__init__.py b/backend/apps/jobs/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/jobs/management/commands/__init__.py b/backend/apps/jobs/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/jobs/management/commands/advance_cycle_days.py b/backend/apps/jobs/management/commands/advance_cycle_days.py new file mode 100644 index 0000000..d08fa79 --- /dev/null +++ b/backend/apps/jobs/management/commands/advance_cycle_days.py @@ -0,0 +1,11 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from apps.farms.models import Cycle + + +class Command(BaseCommand): + help = "Placeholder — advance_cycle_days no longer applicable (current_day removed from ERD)" + + def handle(self, *args, **options): + self.stdout.write("current_day field removed; this command is a no-op now.") diff --git a/backend/apps/jobs/management/commands/bootstrap_admin.py b/backend/apps/jobs/management/commands/bootstrap_admin.py new file mode 100644 index 0000000..058b810 --- /dev/null +++ b/backend/apps/jobs/management/commands/bootstrap_admin.py @@ -0,0 +1,117 @@ +from django.conf import settings +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction + +from apps.accounts.models import ApiKey, User + + +def ensure_bootstrap_user( + *, + user_name: str, + password: str, + status: str, + is_superuser: bool, + force_password: bool, + stdout, +) -> User: + user, created = User.objects.get_or_create( + user_name=user_name, + defaults={ + "status": status, + "is_superuser": is_superuser, + }, + ) + + if not created and user.status != status: + stdout.write( + f"Updating {user_name!r} status {user.status!r} → {status!r}" + ) + + should_set_password = created or not user.has_usable_password() or force_password + if should_set_password: + user.set_password(password) + user.status = status + user.is_superuser = is_superuser + user.save() + action = "Created" if created else "Updated password for" + stdout.write(f"{action} {status} user {user_name}") + else: + user.status = status + user.is_superuser = is_superuser + user.save(update_fields=["status", "is_superuser", "updated_at"]) + stdout.write(f"User {user_name} already exists (password unchanged)") + + return user + + +class Command(BaseCommand): + help = ( + "Create production login accounts only (no demo sites/cycles/data). " + "BOOTSTRAP_ADMIN_* creates the break-glass superuser (ops dashboards + " + "user management; hidden from user lists). Optional BOOTSTRAP_STAFF_* creates a GM." + ) + + def add_arguments(self, parser): + parser.add_argument( + "--force-password", + action="store_true", + help="Reset password even when the user already has one", + ) + + @transaction.atomic + def handle(self, *args, **options): + force_password = options["force_password"] + + admin_user_name = (settings.BOOTSTRAP_ADMIN_USER or "admin").strip() + admin_password = settings.BOOTSTRAP_ADMIN_PASSWORD or "" + if not admin_password: + raise CommandError( + "BOOTSTRAP_ADMIN_PASSWORD is required. Set it in .env before running bootstrap_admin." + ) + + admin = ensure_bootstrap_user( + user_name=admin_user_name, + password=admin_password, + status=User.STATUS_SUPERUSER, + is_superuser=True, + force_password=force_password, + stdout=self.stdout, + ) + + staff_user_name = (settings.BOOTSTRAP_STAFF_USER or "").strip() + staff_password = settings.BOOTSTRAP_STAFF_PASSWORD or "" + if staff_user_name: + if staff_user_name == admin_user_name: + raise CommandError( + "BOOTSTRAP_STAFF_USER must differ from BOOTSTRAP_ADMIN_USER." + ) + if not staff_password: + raise CommandError( + "BOOTSTRAP_STAFF_PASSWORD is required when BOOTSTRAP_STAFF_USER is set." + ) + ensure_bootstrap_user( + user_name=staff_user_name, + password=staff_password, + status=User.STATUS_GM, + is_superuser=False, + force_password=force_password, + stdout=self.stdout, + ) + + bootstrap_key = settings.BOOTSTRAP_API_KEY + if bootstrap_key: + api_key, _ = ApiKey.generate(admin, "bootstrap") + api_key.prefix = bootstrap_key[:8] + api_key.key_hash = ApiKey.hash_key(bootstrap_key) + api_key.save(update_fields=["prefix", "key_hash", "updated_at"]) + self.stdout.write(f"Bootstrap API key installed (prefix={api_key.prefix})") + + accounts = admin_user_name + if staff_user_name: + accounts = f"{admin_user_name}, {staff_user_name}" + self.stdout.write( + self.style.SUCCESS( + f"Bootstrap OK: login={accounts} " + "(no demo farm data — use Pengaturan to add sites/kandang/cycles)" + ) + ) diff --git a/backend/apps/jobs/management/commands/recompute_kpi_rollups.py b/backend/apps/jobs/management/commands/recompute_kpi_rollups.py new file mode 100644 index 0000000..0277c1e --- /dev/null +++ b/backend/apps/jobs/management/commands/recompute_kpi_rollups.py @@ -0,0 +1,58 @@ +from django.core.management.base import BaseCommand +from django.db.models import Sum + +from apps.farms.models import Cycle +from apps.operations.models import ChickenCounting, FeedSacks, KPI +from apps.operations.services.visibility import visible_through_date + + +class Command(BaseCommand): + help = "Recompute simple KPI rollups from ops tables for active cycles" + + def handle(self, *args, **options): + cutoff = visible_through_date() + count = 0 + for cycle in Cycle.objects.filter(status=Cycle.STATUS_ACTIVE): + def visible(model): + return model.objects.filter(cycle=cycle, date__lte=cutoff) + + counting = visible(ChickenCounting).aggregate( + mortality=Sum("mortality_count"), + life=Sum("total_count"), + ) + feed_sack = visible(FeedSacks).order_by("-date", "-pk").first() + + latest_cc = visible(ChickenCounting).order_by("-date").first() + latest_cw = None + latest_fs = feed_sack + latest_mi = None + + from apps.operations.models import ChickenWeight, ManualInput + latest_cw = visible(ChickenWeight).order_by("-date").first() + latest_mi = visible(ManualInput).order_by("-date").first() + + if not all([latest_cc, latest_cw, latest_fs, latest_mi]): + self.stdout.write(f"cycle={cycle.pk} skipped (missing source records)") + continue + + kpi, _ = KPI.objects.update_or_create( + cycle=cycle, + date=latest_cc.date, + defaults={ + "cc": latest_cc, + "cw": latest_cw, + "fs": latest_fs, + "manual": latest_mi, + "mortality_total": counting["mortality"] or 0, + "chicken_life": counting["life"] or cycle.doc_in_count, + "feed_total": feed_sack.feed_use_total if feed_sack else 0, + "chicken_life_percentage": ( + ((counting["life"] or cycle.doc_in_count) / cycle.doc_in_count * 100.0) + if cycle.doc_in_count + else 0.0 + ), + }, + ) + count += 1 + self.stdout.write(f"KPI {kpi.pk} for cycle {cycle.pk}") + self.stdout.write(self.style.SUCCESS(f"Recomputed {count} KPI row(s)")) diff --git a/backend/apps/jobs/management/commands/seed_demo.py b/backend/apps/jobs/management/commands/seed_demo.py new file mode 100644 index 0000000..1cba028 --- /dev/null +++ b/backend/apps/jobs/management/commands/seed_demo.py @@ -0,0 +1,146 @@ +from django.conf import settings +from django.core.management import call_command +from django.core.management.base import BaseCommand +from django.db import transaction + +from apps.accounts.models import ApiKey, User +from apps.farms.models import Site +from apps.sync.models import CitySite + + +# Every executive role + inactive, for local HQ demos. +SEED_USERS = ( + { + # Break-glass: status=superuser (ops + Manajemen Akun). Hidden from user lists. + "user_name": "admin", + "password": "admin123", + "status": User.STATUS_SUPERUSER, + "is_superuser": True, + }, + { + "user_name": "director", + "password": "director123", + "status": User.STATUS_DIRECTOR, + }, + { + "user_name": "director_admin", + "password": "directoradmin123", + "status": User.STATUS_DIRECTOR_ADMIN, + }, + { + "user_name": "buh", + "password": "buh123", + "status": User.STATUS_BUH, + }, + { + "user_name": "bu_admin", + "password": "buadmin123", + "status": User.STATUS_BU_ADMIN, + }, + { + "user_name": "gm", + "password": "gm123", + "status": User.STATUS_GM, + "managed_by": "buh", + }, + { + "user_name": "gm_admin", + "password": "gmadmin123", + "status": User.STATUS_GM_ADMIN, + "managed_by": None, # not on BUH org chart; only GM requests/confirm + }, + { + "user_name": "account_admin", + "password": "accountadmin123", + "status": User.STATUS_ACCOUNT_ADMIN, + }, +) + + +class Command(BaseCommand): + help = ( + "Seed all HQ executive role logins + API key, then Sukawarna Kandang 1 " + "and Kandang 2 as default closed cycles (local mirror demo data). " + "Removes legacy staff login if present." + ) + + def _ensure_user(self, spec: dict, by_name: dict[str, User]) -> User: + managed_by_name = spec.get("managed_by") + managed_by = by_name.get(managed_by_name) if managed_by_name else None + defaults = { + "status": spec["status"], + "is_superuser": spec.get("is_superuser", False), + } + if managed_by is not None: + defaults["managed_by"] = managed_by + + user, created = User.objects.get_or_create( + user_name=spec["user_name"], + defaults=defaults, + ) + user.status = spec["status"] + user.is_superuser = spec.get("is_superuser", False) + if managed_by is not None: + user.managed_by = managed_by + elif "managed_by" in spec: + user.managed_by = None + user.set_password(spec["password"]) + user.save() + + role = spec["status"] + if user.is_superuser: + role = f"{role}+superuser" + link = f", managed_by={managed_by.user_name}" if managed_by else "" + action = "Created" if created else "Updated" + self.stdout.write( + f"{action} user {spec['user_name']} / {spec['password']} ({role}{link})" + ) + return user + + def _remove_legacy_staff(self, gm: User) -> None: + staff = User.objects.filter(user_name="staff").first() + if not staff: + return + moved_sites = Site.objects.filter(user=staff).update(user=gm) + moved_cities = CitySite.objects.filter(registered_by=staff).update(registered_by=gm) + ApiKey.objects.filter(user=staff).delete() + staff.delete() + self.stdout.write( + self.style.WARNING( + f"Removed legacy staff login " + f"(reassigned sites={moved_sites}, city_sites={moved_cities} to gm)" + ) + ) + + @transaction.atomic + def handle(self, *args, **options): + by_name: dict[str, User] = {} + for spec in SEED_USERS: + user = self._ensure_user(spec, by_name) + by_name[user.user_name] = user + + admin = by_name["admin"] + gm = by_name["gm"] + self._remove_legacy_staff(gm) + + bootstrap = settings.BOOTSTRAP_API_KEY + if bootstrap: + api_key, _raw_key = ApiKey.generate(admin, "bootstrap") + api_key.prefix = bootstrap[:8] + api_key.key_hash = ApiKey.hash_key(bootstrap) + api_key.save(update_fields=["prefix", "key_hash", "updated_at"]) + self.stdout.write(f"Bootstrap API key installed (prefix={api_key.prefix})") + elif not ApiKey.objects.filter(user=admin).exists(): + _api_key, raw_key = ApiKey.generate(admin, "seed") + self.stdout.write(self.style.WARNING(f"Demo API key (save now): {raw_key}")) + + call_command("seed_sukawarna_kandang4") + call_command("seed_sukawarna_kandang5") + call_command("seed_iot_10min") + + self.stdout.write( + self.style.SUCCESS( + "Seed OK: all executive roles + Sukawarna cycles + IoT panels " + "(Sukawarna owned by gm)" + ) + ) diff --git a/backend/apps/jobs/management/commands/seed_iot_10min.py b/backend/apps/jobs/management/commands/seed_iot_10min.py new file mode 100644 index 0000000..a0cdf6c --- /dev/null +++ b/backend/apps/jobs/management/commands/seed_iot_10min.py @@ -0,0 +1,239 @@ +"""Seed 10-minute IoT panel readings (144/day) for every flock. + +Kandang 2 Lantai 1 is seeded from real sensor snapshots pulled from +``dashboard.cpsp.id/api/iot/flocks/`` (cached in ``scripts/iot_panel_10min_extract.json``); +every other flock/floor is generated from that data with a deterministic per-house +jitter so each cycle day holds a full 00:00..23:50 run of 144 readings. + +Run ``scripts/extract_iot_10min.py`` to refresh the cache against the live API. +""" +from __future__ import annotations + +import json +import random +from datetime import date as date_cls +from datetime import datetime, time, timedelta +from pathlib import Path + +from django.conf import settings +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction +from django.utils import timezone + +from apps.farms.models import Cycle, Flock + +SLOTS_PER_DAY = 144 # 24h * 6 + +CHILL_FACTOR_POINTS = ( + (0, 8.0), + (1, 8.0), + (7, 7.0), + (14, 6.0), + (21, 4.5), + (28, 3.5), + (35, 3.5), + (42, 3.0), +) + + +def chicken_chill_factor(age: float) -> float: + if age <= CHILL_FACTOR_POINTS[0][0]: + return CHILL_FACTOR_POINTS[0][1] + for idx in range(1, len(CHILL_FACTOR_POINTS)): + prev_age, prev_factor = CHILL_FACTOR_POINTS[idx - 1] + next_age, next_factor = CHILL_FACTOR_POINTS[idx] + if age > next_age: + continue + span = next_age - prev_age + if span <= 0: + return next_factor + progress = (age - prev_age) / span + return prev_factor + (next_factor - prev_factor) * progress + return CHILL_FACTOR_POINTS[-1][1] + + +def experience_temperature( + *, average_temperature: float, wind_speed: float, humidity_pct: float, age_days: float +) -> float: + chill_factor = chicken_chill_factor(age_days) + rh_adjustment = (humidity_pct - 70.0) / 5.0 + chill_effect = wind_speed * chill_factor - rh_adjustment + return average_temperature - chill_effect + + +def lerp(a: float, b: float, frac: float) -> float: + return a + (b - a) * frac + + +def slot_timestamp(day: date_cls, slot: int) -> datetime: + naive = datetime.combine(day, time(0, 0)) + timedelta(minutes=10 * slot) + return timezone.make_aware(naive, timezone.get_current_timezone()) + + +def gap_fill_day(day_rows: dict[int, dict]) -> dict[int, dict]: + """Return 144 slots for a day, interpolating any missing 10-minute windows.""" + present = sorted(day_rows.items()) + filled: dict[int, dict] = {} + for slot in range(SLOTS_PER_DAY): + if slot in day_rows: + filled[slot] = dict(day_rows[slot]) + continue + prev = next = None + for s, row in present: + if s < slot: + prev = (s, row) + elif s > slot and next is None: + next = (s, row) + break + if prev is None and next is not None: + filled[slot] = dict(next[1]) + elif next is None and prev is not None: + filled[slot] = dict(prev[1]) + elif prev is not None and next is not None: + ps, prow = prev + ns, nrow = next + frac = (slot - ps) / (ns - ps) + filled[slot] = { + "wind_speed": lerp(prow["wind_speed"], nrow["wind_speed"], frac), + "humidity": lerp(prow["humidity"], nrow["humidity"], frac), + "water_total": lerp(prow["water_total"], nrow["water_total"], frac), + "average_temperature": lerp( + prow["average_temperature"], nrow["average_temperature"], frac + ), + } + return filled + + +class Command(BaseCommand): + help = "Seed 10-minute IoT panel readings (144/day) for all flocks" + + def add_arguments(self, parser): + parser.add_argument("--iot-json", default="") + parser.add_argument("--cycle-start", default="2026-05-22") + parser.add_argument("--no-reset", action="store_true") + parser.add_argument("--jitter-seed", type=int, default=7) + + def load_real_rows(self, path: Path) -> dict[str, dict[int, dict]]: + if not path.is_file(): + raise CommandError(f"IoT 10-min extract not found: {path}") + data = json.loads(path.read_text(encoding="utf-8")) + by_date: dict[str, dict[int, dict]] = {} + for row in data["rows"]: + ts = datetime.fromisoformat(row["timestamp"]) + slot = (ts.hour * 60 + ts.minute) // 10 + by_date.setdefault(row["date"], {})[slot] = row + return by_date + + @transaction.atomic + def handle(self, *args, **options): + iot_json = options["iot_json"] or str( + Path(settings.BASE_DIR).resolve().parent / "scripts" / "iot_panel_10min_extract.json" + ) + cycle_start = date_cls.fromisoformat(options["cycle_start"]) + real_by_date = self.load_real_rows(Path(iot_json)) + + cycles = Cycle.objects.filter( + start_date=cycle_start, kandang__flocks__isnull=False + ).distinct() + if not cycles: + raise CommandError(f"No cycles starting {cycle_start} with flocks") + + seeded = 0 + for cycle in cycles: + kandang_name = cycle.kandang.kandang_name + for flock in cycle.kandang.flocks.order_by("flock_id"): + profile = self.profile_for(kandang_name, flock.flock_name) + rng = random.Random(options["jitter_seed"] + flock.pk) + rows = self.build_flock_rows(flock, cycle, real_by_date, profile, rng) + if not options["no_reset"]: + flock.iot_panels.all().delete() + for chunk in range(0, len(rows), 500): + flock.iot_panels.bulk_create(rows[chunk : chunk + 500]) + seeded += len(rows) + self.stdout.write( + f" {kandang_name} / {flock.flock_name}: {len(rows)} readings" + ) + + self.stdout.write(self.style.SUCCESS(f"Seeded {seeded} IoT panel readings")) + + def profile_for(self, kandang_name: str, flock_name: str) -> dict: + """Per-house transform applied to the real Kandang 2 Lantai 1 readings.""" + is_lantai1 = flock_name == "Lantai 1" + if kandang_name == "Kandang 2": + if is_lantai1: + return {"real": True} + return { + "wind_delta": -0.05, + "humidity_delta": 1.2, + "temperature_delta": -0.3, + "water_factor": 0.96, + } + # Kandang 1: deterministic jitter (same approach as seed_sukawarna_kandang4). + return { + "temperature_jitter": (-0.4, 0.4), + "humidity_jitter": (-3.0, 3.0), + "wind_jitter": (-0.1, 0.1), + "water_factor": 0.9, + "water_jitter_abs": (-120.0, 120.0), + "humidity_delta": 1.2 if not is_lantai1 else 0.0, + "temperature_delta": -0.3 if not is_lantai1 else 0.0, + } + + def build_flock_rows(self, flock: Flock, cycle: Cycle, real: dict, profile: dict, rng: random.Random) -> list: + from apps.operations.models import IotPanel + + day = cycle.start_date + rows: list[IotPanel] = [] + while day <= cycle.end_date: + iso = day.isoformat() + age_days = (day - cycle.start_date).days + 1 + if profile.get("real"): + source = gap_fill_day(real.get(iso, {})) + else: + source = gap_fill_day(real.get(iso, {})) + + if not source: + day += timedelta(days=1) + continue + + real_total = source.get(SLOTS_PER_DAY - 1, {}).get("water_total", 0.0) or 0.0 + target_total = real_total * profile.get("water_factor", 1.0) + if profile.get("water_jitter_abs"): + target_total += rng.uniform(*profile["water_jitter_abs"]) + target_total = max(0.0, target_total) + water_scale = target_total / real_total if real_total else 0.0 + + for slot in range(SLOTS_PER_DAY): + base = source[slot] + avg_temp = base.get("average_temperature", 0.0) + profile.get("temperature_delta", 0.0) + if profile.get("temperature_jitter"): + avg_temp += rng.uniform(*profile["temperature_jitter"]) + humidity = base.get("humidity", 0.0) + profile.get("humidity_delta", 0.0) + if profile.get("humidity_jitter"): + humidity += rng.uniform(*profile["humidity_jitter"]) + humidity = min(100.0, max(0.0, humidity)) + wind = base.get("wind_speed", 0.0) + profile.get("wind_delta", 0.0) + if profile.get("wind_jitter"): + wind += rng.uniform(*profile["wind_jitter"]) + wind = max(0.0, wind) + water = base.get("water_total", 0.0) * water_scale + exp_temp = experience_temperature( + average_temperature=avg_temp, + wind_speed=wind, + humidity_pct=humidity, + age_days=age_days, + ) + rows.append( + IotPanel( + flock=flock, + date=day, + timestamp=slot_timestamp(day, slot), + wind_speed=round(wind, 2), + humidity=round(humidity, 1), + water_total=round(water, 1), + average_temperature=round(avg_temp, 2), + experience_temperature=round(exp_temp, 2), + ) + ) + day += timedelta(days=1) + return rows \ No newline at end of file diff --git a/backend/apps/jobs/management/commands/seed_sukawarna_kandang4.py b/backend/apps/jobs/management/commands/seed_sukawarna_kandang4.py new file mode 100644 index 0000000..b119dca --- /dev/null +++ b/backend/apps/jobs/management/commands/seed_sukawarna_kandang4.py @@ -0,0 +1,435 @@ +"""Seed Sukawarna / Kandang 1 closed cycle. + +Kandang 1 is a generated dataset modeled on the Kandang 2 seed +(``seed_sukawarna_kandang5``). The two houses run the same 49-day window at +the same site, but Kandang 1 is stocked with 45,000 DOC and performs slightly +better (lower mortality, marginally better FCR / EEF). + +Every daily series is hand-tuned so the numbers stay internally consistent: + +* ``chicken_counting`` – daily mortality sums to the cumulative total; camera + count tracks live population (DOC - mortality - harvest) with coverage noise. +* ``chicken_weight`` – smooth growth curve; weighing continues through + close-out (day 38-48), flock average declines as heavy birds are harvested. +* ``feed_sacks`` – daily use ramps up to ~98 sacks and falls off during + close-out; total use (1,941 sacks) matches close-out FCR ≈ 1.71. +* ``harvest`` – 20 partial harvests day 29-48, 40,700 birds, + 57.47 t live weight, avg ~1,412 g/bird at ~33.1 days; tail harvests leave + fewer than 50 birds in the house at close-out. +* ``kpi`` / ``manual`` – FCR/EEF/lot-weight follow the same formulas as the + Kandang 2 preview: + FCR = feed_total_kg / (harvest_weight_total_g + lot_weight_g) + EEF = life_pct * (avg_harvest_weight/1000) / (FCR * avg_harvest_day) * 100 + lot = chicken_life * average_weight +* ``iot_panel`` – derived from the real Kandang 2 sensor extract with + deterministic per-house jitter (same site, same season). +""" + +from __future__ import annotations + +import json +import math +import random +from datetime import date, timedelta +from pathlib import Path + +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction + +from apps.accounts.models import User +from apps.farms.models import Cycle, Flock, Kandang, Site +from apps.jobs.sukawarna_preview import IOT_EXTRACT_JSON +from apps.operations.models import ( + ChickenCounting, + ChickenWeight, + FeedSacks, + IotPanel, + KPI, + ManualInput, +) + +START_DATE = date(2026, 5, 22) +END_DATE = date(2026, 7, 9) +TOTAL_DAYS = 49 +DOC_IN_WEIGHT = 35 +DOC_IN_COUNT = 45_000 +FLOCK_NAMES = ("Lantai 1", "Lantai 2") + +# --- Daily mortality per age 0..48 (sums to 4,269 ≈ 9.49 % deplesi) --------- +MORTALITY = [ + 42, 58, 74, 78, 68, 62, 60, + 52, 54, 47, 50, 44, 46, 48, + 42, 45, 47, 50, 52, 48, 46, + 44, 47, 42, 50, 58, 65, 72, + 95, 120, 150, 175, 200, 185, 215, + 240, 255, 235, 220, 140, 115, 100, + 85, 60, 65, 50, 45, 28, 0, +] + +# --- Flock average weight (g) per age 0..48 --------------------------------- +# Weighing continues through close-out (day 38-48). As heavy birds are +# harvested first, the remaining flock average weight declines. +AVG_WEIGHT = [ + 35, 47, 62, 80, 100, 123, 148, + 175, 204, 235, 268, 303, 340, 379, + 420, 463, 508, 555, 604, 655, 708, + 763, 820, 879, 940, 1003, 1068, 1135, + 1204, 1275, 1348, 1423, 1500, 1570, 1530, + 1470, 1420, 1360, 1310, 1270, 1230, 1220, + 1200, 1180, 1160, 1140, 1120, 1100, 1080, +] + +# --- Weigh-sample size per age 0..48 (declines with live flock during close-out) --- +SAMPLE_COUNT = [ + 229, 214, 250, 230, 260, 240, 220, + 280, 210, 250, 230, 260, 240, 220, + 270, 250, 230, 260, 240, 220, 280, + 250, 230, 270, 240, 220, 260, 240, + 280, 250, 230, 270, 250, 230, 260, + 240, 220, 250, 180, 150, 120, 100, + 80, 60, 50, 40, 30, 20, 15, +] + +# --- Uniformity (%) per age 0..48 -------------------------------------------- +UNIFORMITY = [ + 0, 45, 62, 70, 66, 74, 71, + 78, 69, 73, 81, 68, 75, 72, + 70, 77, 74, 69, 72, 76, 71, + 73, 68, 74, 70, 72, 66, 69, + 73, 67, 71, 69, 72, 68, 65, + 70, 67, 63, 62, 61, 60, 59, + 58, 57, 56, 55, 54, 53, 52, +] + +# --- Feed used (sacks, 50 kg each) per age 0..48; sums to 1,941 -------------- +FEED_TODAY = [ + 24, 11, 14, 22, 24, 27, 31, + 34, 38, 40, 42, 36, 38, 41, + 44, 48, 59, 66, 74, 85, 89, + 90, 57, 98, 92, 84, 72, 79, + 80, 71, 71, 65, 57, 24, 29, + 14, 13, 12, 8, 3, 3, 5, 8, 0, 8, 2, 4, 4, 1, +] + +# --- Feed delivered (sacks) on delivery days (age -> sacks) ------------------ +# Cumulative intake (1,910 sacks) ends just below usage, a small stock draw. +FEED_IN = { + 1: 120, 4: 130, 7: 140, 10: 150, 13: 160, 16: 170, 19: 150, + 22: 140, 25: 130, 28: 120, 31: 110, 34: 100, 37: 90, 40: 80, 43: 120, +} + +# --- Karung keluar (out) per age 0..48: only during the final week, small --- +# "Out" is NOT the same as usage (tuang). It only happens at the very end of the +# cycle and totals ~20 sacks per house, with a handful of sacks per day. +OUT_TODAY = [0] * 42 + [3, 4, 5, 3, 2, 2, 1] + +# --- Harvest plan: age -> (birds, avg live weight g/bird) -------------------- +# 20 partial harvests day 29-48; the tail harvests clear out the house so the +# leftover flock (chicken_life) at close-out stays under 50 birds. +HARVEST = { + 29: (4_500, 1_310), + 30: (5_000, 1_360), + 31: (5_000, 1_430), + 32: (5_000, 1_490), + 33: (5_000, 1_540), + 34: (4_500, 1_500), + 35: (3_500, 1_440), + 36: (2_500, 1_390), + 37: (2_000, 1_330), + 38: (1_500, 1_280), + 39: (1_000, 1_240), + 40: (500, 1_200), + 41: (120, 1_190), + 42: (100, 1_170), + 43: (90, 1_150), + 44: (80, 1_130), + 45: (90, 1_110), + 46: (80, 1_090), + 47: (80, 1_070), + 48: (60, 1_050), +} + + +def _round(value: float, ndigits: int = 2) -> float: + if math.isclose(value, 0.0, abs_tol=1e-12): + return 0.0 + return round(value, ndigits) + + +def _site_owner() -> User: + gm = User.objects.filter(user_name="gm", status=User.STATUS_GM).first() + if gm is None: + raise CommandError( + "User 'gm' is required. Run `python manage.py seed_demo` first." + ) + return gm + + +class Command(BaseCommand): + help = "Seed Sukawarna / Kandang 1 closed cycle (generated, modeled on Kandang 2)" + + def add_arguments(self, parser): + parser.add_argument("--iot-json", default=str(IOT_EXTRACT_JSON)) + parser.add_argument("--no-reset", action="store_true") + parser.add_argument("--jitter-seed", type=int, default=7) + + @transaction.atomic + def handle(self, *args, **options): + iot_path = Path(options["iot_json"]) + if not iot_path.is_file(): + raise CommandError(f"IoT extract not found: {iot_path}") + iot = json.loads(iot_path.read_text(encoding="utf-8")) + rng = random.Random(options["jitter_seed"]) + + user = _site_owner() + site, _ = Site.objects.get_or_create(site_name="Sukawarna", defaults={"user": user}) + if site.user_id != user.pk: + site.user = user + site.save(update_fields=["user", "updated_at"]) + self.stdout.write(f"Sukawarna site owner: {user.user_name} ({user.status})") + + kandang, _ = Kandang.objects.get_or_create( + kandang_name="Kandang 1", + site=site, + ) + + existing = Cycle.objects.filter(kandang=kandang, start_date=START_DATE).first() + if existing and not options["no_reset"]: + KPI.objects.filter(cycle=existing).delete() + ChickenCounting.objects.filter(cycle=existing).delete() + ChickenWeight.objects.filter(cycle=existing).delete() + FeedSacks.objects.filter(cycle=existing).delete() + ManualInput.objects.filter(cycle=existing).delete() + IotPanel.objects.filter( + flock__kandang=kandang, + date__gte=existing.start_date, + date__lte=existing.end_date, + ).delete() + existing.delete() + self.stdout.write("Reset previous Kandang 1 cycle") + + cycle, cycle_created = Cycle.objects.get_or_create( + kandang=kandang, + start_date=START_DATE, + defaults={ + "end_date": END_DATE, + "total_days": TOTAL_DAYS, + "doc_in_weight": DOC_IN_WEIGHT, + "doc_in_count": DOC_IN_COUNT, + "status": Cycle.STATUS_CLOSED, + }, + ) + if not cycle_created: + cycle.end_date = END_DATE + cycle.total_days = TOTAL_DAYS + cycle.doc_in_weight = DOC_IN_WEIGHT + cycle.doc_in_count = DOC_IN_COUNT + cycle.status = Cycle.STATUS_CLOSED + cycle.save() + + flocks_by_name: dict[str, Flock] = {} + for name in FLOCK_NAMES: + flock, _ = Flock.objects.get_or_create(flock_name=name, kandang=kandang) + flocks_by_name[name] = flock + + dates = [START_DATE + timedelta(days=i) for i in range(TOTAL_DAYS)] + + # --- cumulative series ------------------------------------------------- + mort_total = 0 + harvest_total = 0 + harvest_weight_total = 0.0 + feed_total = 0 + feed_in_total = 0 + out_total = 0 + + cc_by_date: dict[date, ChickenCounting] = {} + cw_by_date: dict[date, ChickenWeight] = {} + fs_by_date: dict[date, FeedSacks] = {} + manual_by_date: dict[date, ManualInput] = {} + + harvest_day_accum = 0.0 # Σ (harvest × age) + harvest_wt_accum = 0.0 # Σ (harvest × batch avg weight) + + for i, day in enumerate(dates): + age = i + live = DOC_IN_COUNT - mort_total - harvest_total + + # --- chicken_counting ----------------------------------------- + quality = "ok" if age < 34 else "atas_only" + coverage = 0.82 + 0.16 * math.sin(i / 1.9) - 0.011 * min(i, 36) + camera_count = max(1, int(round(live * max(coverage, 0.3)))) + cc, _ = ChickenCounting.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "total_count": camera_count, + "mortality_count": MORTALITY[i], + }, + ) + cc_by_date[day] = cc + + # --- chicken_weight -------------------------------------------- + weight = AVG_WEIGHT[i] + prev_weight = AVG_WEIGHT[i - 1] if i > 0 else DOC_IN_WEIGHT + adg = _round(weight - prev_weight, 2) if weight else 0.0 + cw, _ = ChickenWeight.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "age": age, + "doc_weight": DOC_IN_WEIGHT, + "average_weight": weight, + "chicken_count": SAMPLE_COUNT[i], + "uniformity": UNIFORMITY[i], + "average_daily_gain": adg, + }, + ) + cw_by_date[day] = cw + + # --- feed_sacks ------------------------------------------------ + feed_today = FEED_TODAY[i] + in_today = FEED_IN.get(age, 0) + out_today = OUT_TODAY[i] + feed_total += feed_today + feed_in_total += in_today + out_total += out_today + fs, _ = FeedSacks.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "in_today": in_today, + "out_today": out_today, + "in_total": feed_in_total, + "out_total": out_total, + "feed_use_today": feed_today, + "feed_use_total": feed_total, + }, + ) + fs_by_date[day] = fs + + # --- harvest (manual) ------------------------------------------ + harvest_today, harvest_wt_today = HARVEST.get(age, (0, 0)) + if harvest_today: + harvest_total += harvest_today + harvest_weight_total += harvest_today * harvest_wt_today + harvest_day_accum += harvest_today * age + harvest_wt_accum += harvest_today * harvest_wt_today + + mort_today = MORTALITY[i] + mort_total_after = mort_total + mort_today + life = DOC_IN_COUNT - mort_total_after - harvest_total + # Liveability for EEF: birds still accounted for (DOC minus mortality), + # not remaining in-house stock (which drops during harvest). + life_pct = (DOC_IN_COUNT - mort_total_after) / DOC_IN_COUNT * 100.0 if DOC_IN_COUNT else 0.0 + # Running averages: flock weight before the first harvest, then the + # harvest-weighted running mean carried forward on idle days. + if harvest_today: + avg_hday = harvest_day_accum / harvest_total + avg_hwt = harvest_wt_accum / harvest_total + elif harvest_total == 0: + avg_hday = float(age) + avg_hwt = float(weight) if weight else 0.0 + else: + avg_hday = harvest_day_accum / harvest_total + avg_hwt = harvest_wt_accum / harvest_total + + lot_weight_g = life * weight if weight else 0.0 + denom = harvest_weight_total + lot_weight_g + fcr = (feed_total * 50_000) / denom if denom > 0 else 0.0 + if avg_hday > 0 and fcr > 0: + eef = life_pct * (avg_hwt / 1000.0) / (fcr * avg_hday) * 100.0 + else: + eef = 0.0 + + manual, _ = ManualInput.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "age_manual": age, + "mortality_manual": mort_today, + "mortality_manual_total": mort_total_after, + "feed_in_manual": in_today, + "feed_in_manual_total": feed_in_total, + "feed_use_manual": feed_today, + "feed_use_manual_total": feed_total, + "feed_out_manual": out_today, + "feed_out_manual_total": out_total, + "harvest_manual": harvest_today, + "harvest_manual_total": harvest_total, + "harvest_weight_manual": float(harvest_today * harvest_wt_today), + "harvest_weight_manual_total": harvest_weight_total, + "manual_weight": weight, + "average_harvest_day_manual": _round(avg_hday, 4), + "average_harvest_weight_manual": _round(avg_hwt, 4), + "fcr_manual": _round(fcr, 4), + "eef_manual": _round(eef, 4), + }, + ) + manual_by_date[day] = manual + + # --- KPI --------------------------------------------------------- + KPI.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "age": age, + "mortality": mort_today, + "mortality_total": mort_total_after, + "feed": feed_today, + "feed_total": feed_total, + "harvest": harvest_today, + "harvest_total": harvest_total, + "harvest_weight": float(harvest_today * harvest_wt_today), + "harvest_weight_total": harvest_weight_total, + "chicken_life": life, + "chicken_life_percentage": _round(life_pct, 3), + "iot_weight": _round(lot_weight_g, 2), + "average_harvest_day": _round(avg_hday, 4), + "average_harvest_weight": _round(avg_hwt, 4), + "fcr": _round(fcr, 4), + "eef": _round(eef, 4), + "cc": cc, + "cw": cw, + "fs": fs, + "manual": manual, + }, + ) + + mort_total = mort_total_after + + # --- IoT panel: Kandang 2 sensors with per-house jitter ------------- + panel_count = 0 + for flock_block in iot["flocks"]: + flock = flocks_by_name[flock_block["name"]] + for row in flock_block["rows"]: + day = date.fromisoformat(row["date"]) + avg_temp = float(row["average_temperature"]) + rng.uniform(-0.4, 0.4) + humidity = min(max(float(row["humidity"]) + rng.uniform(-3.0, 3.0), 0.0), 100.0) + wind = max(float(row["wind_speed"]) + rng.uniform(-0.1, 0.1), 0.0) + water = max(float(row["water_total"]) * 0.9 + rng.uniform(-120.0, 120.0), 0.0) + chill = float(row["chill_factor"]) + exp_temp = avg_temp - (70.0 - humidity) / 5.0 - wind * chill + IotPanel.objects.update_or_create( + flock=flock, + date=day, + defaults={ + "wind_speed": _round(wind, 2), + "humidity": _round(humidity, 1), + "water_total": _round(water, 1), + "average_temperature": _round(avg_temp, 2), + "experience_temperature": _round(exp_temp, 4), + }, + ) + panel_count += 1 + + last_kpi = KPI.objects.filter(cycle=cycle).order_by("-date").first() + self.stdout.write( + self.style.SUCCESS( + f"Seeded cycle={cycle.pk} site={site.pk} kandang={kandang.pk} " + f"flocks={Flock.objects.filter(kandang=kandang).count()} " + f"cc={len(cc_by_date)} cw={len(cw_by_date)} fs={len(fs_by_date)} " + f"manual={len(manual_by_date)} kpi={KPI.objects.filter(cycle=cycle).count()} " + f"iot_panel={panel_count} closeout_fcr={last_kpi.fcr if last_kpi else None} " + f"closeout_eef={last_kpi.eef if last_kpi else None}" + ) + ) diff --git a/backend/apps/jobs/management/commands/seed_sukawarna_kandang5.py b/backend/apps/jobs/management/commands/seed_sukawarna_kandang5.py new file mode 100644 index 0000000..de85ec1 --- /dev/null +++ b/backend/apps/jobs/management/commands/seed_sukawarna_kandang5.py @@ -0,0 +1,293 @@ +from __future__ import annotations + +import json +from datetime import date +from pathlib import Path + +from django.core.management.base import BaseCommand, CommandError +from django.db import transaction + +from apps.accounts.models import User +from apps.farms.models import Cycle, Flock, Kandang, Site +from apps.jobs.sukawarna_preview import ( + FEED_REFERENCE_XLSX, + IOT_EXTRACT_JSON, + PREVIEW_XLSX, + as_number, + load_feed_reference, + load_preview, +) +from apps.operations.models import ( + ChickenCounting, + ChickenWeight, + FeedSacks, + IotPanel, + KPI, + ManualInput, +) + +# --- Karung keluar (out) per cycle day 0..48: only during the final week ---- +# "Out" is NOT the same as usage (tuang). It only happens at the very end of the +# cycle and totals ~20 sacks per house, with a handful of sacks per day. +OUT_TODAY = [0] * 42 + [4, 5, 4, 3, 2, 1, 1] + + +def _site_owner() -> User: + gm = User.objects.filter(user_name="gm", status=User.STATUS_GM).first() + if gm is None: + raise CommandError( + "User 'gm' is required. Run `python manage.py seed_demo` first." + ) + return gm + + +class Command(BaseCommand): + help = "Seed Sukawarna / Kandang 2 closed cycle from preview xlsx + IoT extract" + + def add_arguments(self, parser): + parser.add_argument("--xlsx", default=str(PREVIEW_XLSX)) + parser.add_argument("--iot-json", default=str(IOT_EXTRACT_JSON)) + parser.add_argument("--feed-reference", default=str(FEED_REFERENCE_XLSX)) + parser.add_argument("--no-reset", action="store_true") + + @transaction.atomic + def handle(self, *args, **options): + xlsx = Path(options["xlsx"]) + iot_path = Path(options["iot_json"]) + feed_reference_path = Path(options["feed_reference"]) + if not xlsx.is_file(): + raise CommandError(f"Preview not found: {xlsx}") + if not iot_path.is_file(): + raise CommandError(f"IoT extract not found: {iot_path}") + + sheets = load_preview(xlsx) + iot = json.loads(iot_path.read_text(encoding="utf-8")) + feed_reference = {} + if feed_reference_path.is_file(): + feed_reference = load_feed_reference(feed_reference_path) + else: + self.stderr.write(f"Feed reference not found, continuing without it: {feed_reference_path}") + + user = _site_owner() + site, _ = Site.objects.get_or_create(site_name="Sukawarna", defaults={"user": user}) + if site.user_id != user.pk: + site.user = user + site.save(update_fields=["user", "updated_at"]) + self.stdout.write(f"Sukawarna site owner: {user.user_name} ({user.status})") + + kandang, _ = Kandang.objects.get_or_create( + kandang_name="Kandang 2", + site=site, + ) + + start_date = date(2026, 5, 22) + end_date = date(2026, 7, 9) + + existing = Cycle.objects.filter(kandang=kandang, start_date=start_date).first() + if existing and not options["no_reset"]: + KPI.objects.filter(cycle=existing).delete() + ChickenCounting.objects.filter(cycle=existing).delete() + ChickenWeight.objects.filter(cycle=existing).delete() + FeedSacks.objects.filter(cycle=existing).delete() + ManualInput.objects.filter(cycle=existing).delete() + IotPanel.objects.filter( + flock__kandang=kandang, + date__gte=existing.start_date, + date__lte=existing.end_date, + ).delete() + existing.delete() + self.stdout.write("Reset previous Kandang 2 cycle") + + cycle, cycle_created = Cycle.objects.get_or_create( + kandang=kandang, + start_date=start_date, + defaults={ + "end_date": end_date, + "total_days": 49, + "doc_in_weight": 35, + "doc_in_count": 50000, + "status": Cycle.STATUS_CLOSED, + }, + ) + if not cycle_created: + cycle.end_date = end_date + cycle.total_days = 49 + cycle.doc_in_weight = 35 + cycle.doc_in_count = 50000 + cycle.status = Cycle.STATUS_CLOSED + cycle.save() + + flocks_by_name: dict[str, Flock] = {} + for name in ("Lantai 1", "Lantai 2"): + flock, _ = Flock.objects.get_or_create(flock_name=name, kandang=kandang) + flocks_by_name[name] = flock + + cc_by_date = {} + for row in sheets["chicken_counting"]: + obj, _ = ChickenCounting.objects.update_or_create( + cycle=cycle, + date=row["date"], + defaults={ + "total_count": int(as_number(row.get("total_count"))), + "mortality_count": int(as_number(row.get("mortality_count"))), + }, + ) + cc_by_date[row["date"]] = obj + + cw_by_date = {} + for row in sheets["chicken_weight"]: + obj, _ = ChickenWeight.objects.update_or_create( + cycle=cycle, + date=row["date"], + defaults={ + "age": int(as_number(row.get("age"))), + "doc_weight": int(as_number(row.get("doc_weight"))), + "average_weight": float(as_number(row.get("average_weight"))), + "chicken_count": int(as_number(row.get("chicken_count"))), + "uniformity": float(as_number(row.get("uniformity"))), + "average_daily_gain": float(as_number(row.get("average_daily_gain"))), + }, + ) + cw_by_date[row["date"]] = obj + + fs_by_date = {} + fs_in_total = 0 + fs_use_total = 0 + fs_out_total = 0 + for row in sheets["feed_sacks"]: + day = row["date"] + ref = feed_reference.get(day.isoformat()) + in_today = int(ref["iot_in"]) if ref else int(as_number(row.get("in_today"))) + feed_use_today = ( + int(ref["iot_use"]) if ref else int(as_number(row.get("out_today"))) + ) + out_today = OUT_TODAY[(day - start_date).days] + fs_in_total += in_today + fs_use_total += feed_use_today + fs_out_total += out_today + obj, _ = FeedSacks.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "in_today": in_today, + "out_today": out_today, + "in_total": fs_in_total, + "out_total": fs_out_total, + "feed_use_today": feed_use_today, + "feed_use_total": fs_use_total, + }, + ) + fs_by_date[day] = obj + + manual_by_date = {} + manual_in_total = 0 + manual_use_total = 0 + manual_out_total = 0 + for row in sheets["manual_input"]: + day = row["date"] + ref = feed_reference.get(day.isoformat()) + feed_in_manual = int(ref["manual_in"]) if ref else ( + int(fs_row.in_today) if (fs_row := fs_by_date.get(day)) else 0 + ) + feed_use_manual = int(ref["manual_use"]) if ref else int(as_number(row.get("feed_manual"))) + feed_out_manual = OUT_TODAY[(day - start_date).days] + manual_in_total += feed_in_manual + manual_use_total += feed_use_manual + manual_out_total += feed_out_manual + obj, _ = ManualInput.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "age_manual": int(as_number(row.get("age_manual"))), + "mortality_manual": int(as_number(row.get("mortality_manual"))), + "mortality_manual_total": int(as_number(row.get("mortality_manual_total"))), + "feed_in_manual": feed_in_manual, + "feed_in_manual_total": manual_in_total, + "feed_use_manual": feed_use_manual, + "feed_use_manual_total": manual_use_total, + "feed_out_manual": feed_out_manual, + "feed_out_manual_total": manual_out_total, + "harvest_manual": int(as_number(row.get("harvest_manual"))), + "harvest_manual_total": int(as_number(row.get("harvest_manual_total"))), + "harvest_weight_manual": float(as_number(row.get("harvest_weight_manual"))), + "harvest_weight_manual_total": float( + as_number(row.get("harvest_weight_manual_total")) + ), + "manual_weight": float( + as_number(row.get("manual_weight_float") or row.get("manual_weight")) + ), + "average_harvest_day_manual": float( + as_number(row.get("average_harvest_day_manual")) + ), + "average_harvest_weight_manual": float( + as_number(row.get("average_harvest_weight_manual")) + ), + "fcr_manual": float(as_number(row.get("fcr_manual"))), + "eef_manual": float(as_number(row.get("eef_manual"))), + }, + ) + manual_by_date[day] = obj + + missing = [] + for row in sheets["kpi_preview"]: + day = row["date"] + try: + KPI.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "age": int(as_number(row.get("age"))), + "mortality": int(as_number(row.get("deplesi"))), + "mortality_total": int(as_number(row.get("deplesi_total"))), + "feed": int(as_number(row.get("feed_use_manual"))), + "feed_total": int(as_number(row.get("feed_use_total_manual"))), + "harvest": int(as_number(row.get("panen"))), + "harvest_total": int(as_number(row.get("panen_total"))), + "harvest_weight": float(as_number(row.get("harvest_weight_g"))), + "harvest_weight_total": float(as_number(row.get("harvest_weight_total_g"))), + "chicken_life": int(as_number(row.get("chicken_life"))), + "chicken_life_percentage": float(as_number(row.get("chicken_life_pct"))), + "iot_weight": float(as_number(row.get("lot_weight_g"))), + "average_harvest_day": float(as_number(row.get("avg_harvest_day"))), + "average_harvest_weight": float(as_number(row.get("avg_harvest_weight_g"))), + "fcr": float(as_number(row.get("fcr"))), + "eef": float(as_number(row.get("eef"))), + "cc": cc_by_date[day], + "cw": cw_by_date[day], + "fs": fs_by_date[day], + "manual": manual_by_date[day], + }, + ) + except KeyError: + missing.append(str(day)) + if missing: + raise CommandError(f"KPI dates missing source rows: {missing}") + + panel_count = 0 + for flock_block in iot["flocks"]: + flock = flocks_by_name[flock_block["name"]] + for row in flock_block["rows"]: + day = date.fromisoformat(row["date"]) + IotPanel.objects.update_or_create( + flock=flock, + date=day, + defaults={ + "wind_speed": float(row["wind_speed"]), + "humidity": float(row["humidity"]), + "water_total": float(row["water_total"]), + "average_temperature": float(row["average_temperature"]), + "experience_temperature": float(row["experience_temperature"]), + }, + ) + panel_count += 1 + + last_kpi = KPI.objects.filter(cycle=cycle).order_by("-date").first() + self.stdout.write( + self.style.SUCCESS( + f"Seeded cycle={cycle.pk} site={site.pk} kandang={kandang.pk} " + f"flocks={Flock.objects.filter(kandang=kandang).count()} " + f"cc={len(cc_by_date)} cw={len(cw_by_date)} fs={len(fs_by_date)} " + f"manual={len(manual_by_date)} kpi={KPI.objects.filter(cycle=cycle).count()} " + f"iot_panel={panel_count} closeout_fcr={last_kpi.fcr if last_kpi else None}" + ) + ) diff --git a/backend/apps/jobs/management/commands/sync_chicken_counting_from_edge.py b/backend/apps/jobs/management/commands/sync_chicken_counting_from_edge.py new file mode 100644 index 0000000..1446ed4 --- /dev/null +++ b/backend/apps/jobs/management/commands/sync_chicken_counting_from_edge.py @@ -0,0 +1,45 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from apps.farms.models import Cycle +from apps.operations.services.chicken_counting_edge import ( + ChickenCountingEdgeError, + sync_chicken_counting_for_cycle, +) + + +class Command(BaseCommand): + help = "Sync chicken counting + mortality IoT from the edge vision API" + + def add_arguments(self, parser): + parser.add_argument("--cycle-id", type=int, default=None) + + def handle(self, *args, **options): + counting_on = settings.CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED + mortality_on = settings.CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED + if not counting_on and not mortality_on: + self.stdout.write( + "CHICKEN_COUNTING_EDGE_*_SYNC_ENABLED=false; skipping" + ) + return + + cycle_id = options.get("cycle_id") + if cycle_id: + cycles = Cycle.objects.filter(pk=cycle_id).select_related("kandang") + else: + cycles = Cycle.objects.filter(status=Cycle.STATUS_ACTIVE).select_related( + "kandang" + ) + + for cycle in cycles: + try: + summary = sync_chicken_counting_for_cycle(cycle) + except ChickenCountingEdgeError as exc: + self.stderr.write(f"cycle={cycle.pk}: {exc}") + continue + self.stdout.write( + self.style.SUCCESS( + f"cycle={cycle.pk} upserted={summary['upserted']} " + f"dates={','.join(d.isoformat() for d in summary['dates']) or '-'}" + ) + ) diff --git a/backend/apps/jobs/management/commands/sync_iot_from_api.py b/backend/apps/jobs/management/commands/sync_iot_from_api.py new file mode 100644 index 0000000..1f2ff46 --- /dev/null +++ b/backend/apps/jobs/management/commands/sync_iot_from_api.py @@ -0,0 +1,23 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from apps.operations.services.iot_api import IotApiError, sync_iot_panels + + +class Command(BaseCommand): + help = "Sync IoT panel readings from the external IoT flocks API (10-minute snapshots)" + + def handle(self, *args, **options): + if not settings.IOT_SYNC_ENABLED: + self.stdout.write("IOT_SYNC_ENABLED=false; skipping") + return + try: + summary = sync_iot_panels() + except IotApiError as exc: + self.stderr.write(str(exc)) + return + self.stdout.write( + self.style.SUCCESS( + f"IoT sync OK: upserted={summary.upserted} skipped={summary.skipped} pages={summary.pages}" + ) + ) diff --git a/backend/apps/jobs/management/commands/sync_karung_from_web_admin.py b/backend/apps/jobs/management/commands/sync_karung_from_web_admin.py new file mode 100644 index 0000000..bad60df --- /dev/null +++ b/backend/apps/jobs/management/commands/sync_karung_from_web_admin.py @@ -0,0 +1,29 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from apps.farms.models import Cycle +from apps.operations.services.karung_web import KarungWebError, sync_karung_for_cycle + + +class Command(BaseCommand): + help = "Sync FeedSacks rows from karung-web-admin (today sections + combined history)" + + def handle(self, *args, **options): + if not settings.KARUNG_WEB_ADMIN_SYNC_ENABLED: + self.stdout.write("KARUNG_WEB_ADMIN_SYNC_ENABLED=false; skipping") + return + synced = 0 + for cycle in Cycle.objects.filter(status=Cycle.STATUS_ACTIVE): + try: + feed_sack, summary = sync_karung_for_cycle(cycle, section="today") + synced += 1 + self.stdout.write( + f"cycle={cycle.pk} in_today={feed_sack.in_today} " + f"out_today={feed_sack.out_today} date={summary.get('snapshot_date')} " + f"history={','.join(summary.get('history_dates') or [])}" + ) + except KarungWebError as exc: + self.stderr.write(f"cycle={cycle.pk} error={exc}") + except Exception as exc: # noqa: BLE001 + self.stderr.write(f"cycle={cycle.pk} unexpected={exc}") + self.stdout.write(self.style.SUCCESS(f"Synced {synced} feed sack row(s)")) diff --git a/backend/apps/jobs/sukawarna_preview.py b/backend/apps/jobs/sukawarna_preview.py new file mode 100644 index 0000000..cbd695d --- /dev/null +++ b/backend/apps/jobs/sukawarna_preview.py @@ -0,0 +1,104 @@ +"""Load Sukawarna / Kandang 2 preview sheets into ORM-ready row dicts.""" + +from __future__ import annotations + +from datetime import date, datetime +from pathlib import Path +from typing import Any + +from openpyxl import load_workbook + +REPO_ROOT = Path(__file__).resolve().parents[3] +PREVIEW_XLSX = REPO_ROOT / "backup" / "kandang5_sukawarna_preview.xlsx" +IOT_EXTRACT_JSON = REPO_ROOT / "scripts" / "iot_panel_cycle_extract.json" +# Final-cycle report (reference for manual feed use on Kandang 2). +FEED_REFERENCE_XLSX = ( + REPO_ROOT + / "backup" + / "Laporan_Akhir-Siklus_Sukawarna_Kandang-Atas_Akhir-Siklus_2026-05-22_sd_2026-07-09.xlsx" +) + + +def as_date(value: Any) -> date | None: + if value is None: + return None + if isinstance(value, datetime): + return value.date() + if isinstance(value, date): + return value + text = str(value).strip() + if len(text) >= 10 and text[0].isdigit() and text[4] == "-": + return date.fromisoformat(text[:10]) + return None + + +def as_number(value: Any, default: float | int = 0): + if value is None or value == "": + return default + if isinstance(value, (int, float)) and not isinstance(value, bool): + return value + try: + if isinstance(value, str) and "." not in value: + return int(value) + return float(value) + except (TypeError, ValueError): + return default + + +def dated_rows(ws) -> list[dict[str, Any]]: + headers = [cell.value for cell in next(ws.iter_rows(min_row=1, max_row=1))] + rows: list[dict[str, Any]] = [] + for raw in ws.iter_rows(min_row=2, values_only=True): + mapped = {str(headers[i]): raw[i] for i in range(len(headers))} + parsed = as_date(mapped.get("date")) + if parsed is None: + continue + mapped["date"] = parsed + rows.append(mapped) + return rows + + +def load_preview(path: Path | None = None) -> dict[str, list[dict[str, Any]]]: + workbook = load_workbook(path or PREVIEW_XLSX, data_only=True) + return { + "chicken_counting": dated_rows(workbook["chicken_counting"]), + "chicken_weight": dated_rows(workbook["chicken_weight"]), + "feed_sacks": dated_rows(workbook["feed_sacks"]), + "manual_input": dated_rows(workbook["manual_input"]), + "kpi_preview": dated_rows(workbook["kpi_preview"]), + } + + +def load_feed_reference(path: Path | None = None) -> dict[str, dict[str, int]]: + """Load the final-cycle report's Feed In / Feed Use sheets. + + Returns ``{date: {manual_in, iot_in, manual_use, iot_use}}``. These values are + the authoritative reference for the karung "Manual" / "IOT" columns. + """ + workbook = load_workbook(path or FEED_REFERENCE_XLSX, data_only=True) + + feed_in: dict[str, dict[str, int]] = {} + for raw in workbook["Feed In"].iter_rows(min_row=3, values_only=True): + parsed = as_date(raw[0]) + if parsed is None: + continue + feed_in[parsed.isoformat()] = { + "manual_in": int(as_number(raw[1])), + "iot_in": int(as_number(raw[2])), + } + + feed_use: dict[str, dict[str, int]] = {} + for raw in workbook["Feed Use"].iter_rows(min_row=3, values_only=True): + parsed = as_date(raw[0]) + if parsed is None: + continue + feed_use[parsed.isoformat()] = { + "manual_use": int(as_number(raw[2])), + "iot_use": int(as_number(raw[3])), + } + + merged: dict[str, dict[str, int]] = {} + for key in feed_in: + if key in feed_use: + merged[key] = {**feed_in[key], **feed_use[key]} + return merged diff --git a/backend/apps/jobs/tests.py b/backend/apps/jobs/tests.py new file mode 100644 index 0000000..053862b --- /dev/null +++ b/backend/apps/jobs/tests.py @@ -0,0 +1,55 @@ +from django.core.management.base import CommandError +from django.test import TestCase, override_settings + +from apps.accounts.models import User +from apps.farms.models import Cycle, Site +from django.core.management import call_command + + +@override_settings( + BOOTSTRAP_ADMIN_USER="admin", + BOOTSTRAP_ADMIN_PASSWORD="Pr04dm1n", + BOOTSTRAP_STAFF_USER="", + BOOTSTRAP_STAFF_PASSWORD="", +) +class BootstrapAdminTests(TestCase): + def test_creates_break_glass_superuser_without_demo_data(self): + call_command("bootstrap_admin") + user = User.objects.get(user_name="admin") + self.assertEqual(user.status, User.STATUS_SUPERUSER) + self.assertTrue(user.is_superuser) + self.assertTrue(user.check_password("Pr04dm1n")) + self.assertFalse(Site.objects.exists()) + self.assertFalse(Cycle.objects.exists()) + + def test_requires_password(self): + with self.settings(BOOTSTRAP_ADMIN_PASSWORD=""): + with self.assertRaises(CommandError): + call_command("bootstrap_admin") + + @override_settings( + BOOTSTRAP_STAFF_USER="staff", + BOOTSTRAP_STAFF_PASSWORD="St4ff!", + ) + def test_creates_gm_when_configured(self): + call_command("bootstrap_admin") + staff = User.objects.get(user_name="staff") + self.assertEqual(staff.status, User.STATUS_GM) + self.assertFalse(staff.is_superuser) + self.assertTrue(staff.check_password("St4ff!")) + + @override_settings( + BOOTSTRAP_STAFF_USER="staff", + BOOTSTRAP_STAFF_PASSWORD="", + ) + def test_requires_staff_password_when_user_set(self): + with self.assertRaises(CommandError): + call_command("bootstrap_admin") + + @override_settings( + BOOTSTRAP_STAFF_USER="admin", + BOOTSTRAP_STAFF_PASSWORD="St4ff!", + ) + def test_rejects_staff_same_as_admin(self): + with self.assertRaises(CommandError): + call_command("bootstrap_admin") diff --git a/backend/apps/operations/__init__.py b/backend/apps/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/operations/apps.py b/backend/apps/operations/apps.py new file mode 100644 index 0000000..832bcfd --- /dev/null +++ b/backend/apps/operations/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class OperationsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.operations" + label = "operations" + verbose_name = "Operations" diff --git a/backend/apps/operations/migrations/0001_initial.py b/backend/apps/operations/migrations/0001_initial.py new file mode 100644 index 0000000..40eba52 --- /dev/null +++ b/backend/apps/operations/migrations/0001_initial.py @@ -0,0 +1,199 @@ +# Generated by Django 5.2.17 on 2026-08-18 08:01 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('farms', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='AIInsight', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('insight_text', models.TextField()), + ('alert', models.CharField(max_length=100)), + ('section', models.CharField(max_length=100)), + ('session', models.CharField(max_length=100)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ai_insights', to='farms.cycle')), + ], + options={ + 'db_table': 'ai_insight', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='ChickenCounting', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('total_count', models.IntegerField(default=0)), + ('mortality_count', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chicken_countings', to='farms.cycle')), + ], + options={ + 'db_table': 'chicken_counting', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='ChickenWeight', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('age', models.IntegerField()), + ('doc_weight', models.IntegerField()), + ('average_weight', models.FloatField()), + ('chicken_count', models.IntegerField()), + ('uniformity', models.FloatField()), + ('average_daily_gain', models.FloatField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chicken_weights', to='farms.cycle')), + ], + options={ + 'db_table': 'chicken_weight', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='FeedSacks', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('in_today', models.IntegerField(default=0)), + ('out_today', models.IntegerField(default=0)), + ('in_total', models.IntegerField(default=0)), + ('out_total', models.IntegerField(default=0)), + ('feed_use_today', models.IntegerField(default=0)), + ('feed_use_total', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feed_sacks', to='farms.cycle')), + ], + options={ + 'verbose_name_plural': 'Feed sacks', + 'db_table': 'feed_sacks', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='IotPanel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('wind_speed', models.FloatField(default=0.0)), + ('humidity', models.FloatField(default=0.0)), + ('water_total', models.FloatField(default=0.0)), + ('average_temperature', models.FloatField(default=0.0)), + ('experience_temperature', models.FloatField(default=0.0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('flock', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='iot_panels', to='farms.flock')), + ], + options={ + 'verbose_name': 'IoT Panel', + 'verbose_name_plural': 'IoT Panels', + 'db_table': 'iot_panel', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='ManualInput', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('age_manual', models.IntegerField(default=0)), + ('mortality_manual', models.IntegerField(default=0)), + ('mortality_manual_total', models.IntegerField(default=0)), + ('feed_manual', models.IntegerField(default=0)), + ('feed_manual_total', models.IntegerField(default=0)), + ('harvest_manual', models.IntegerField(default=0)), + ('harvest_manual_total', models.IntegerField(default=0)), + ('harvest_weight_manual', models.IntegerField(default=0)), + ('harvest_weight_manual_total', models.IntegerField(default=0)), + ('manual_weight_float', models.FloatField(default=0.0)), + ('average_harvest_day_manual', models.FloatField(default=0.0)), + ('average_harvest_weight_manual', models.FloatField(default=0.0)), + ('fcr_manual', models.FloatField(default=0.0)), + ('eef_manual', models.FloatField(default=0.0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='manual_inputs', to='farms.cycle')), + ], + options={ + 'db_table': 'manual_input', + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='KPI', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('age', models.IntegerField(default=0)), + ('mortality', models.IntegerField(default=0)), + ('mortality_total', models.IntegerField(default=0)), + ('feed', models.IntegerField(default=0)), + ('feed_total', models.IntegerField(default=0)), + ('harvest', models.IntegerField(default=0)), + ('harvest_total', models.IntegerField(default=0)), + ('harvest_weight', models.IntegerField(default=0)), + ('harvest_weight_total', models.IntegerField(default=0)), + ('chicken_life', models.IntegerField(default=0)), + ('chicken_life_percentage', models.FloatField(default=0.0)), + ('lot_weight', models.FloatField(default=0.0)), + ('average_harvest_day', models.FloatField(default=0.0)), + ('average_harvest_weight', models.FloatField(default=0.0)), + ('fcr', models.FloatField(default=0.0)), + ('eef', models.FloatField(default=0.0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('cc', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='kpis', to='operations.chickencounting')), + ('cw', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='kpis', to='operations.chickenweight')), + ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='kpis', to='farms.cycle')), + ('fs', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='kpis', to='operations.feedsacks')), + ('manual', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='kpis', to='operations.manualinput')), + ], + options={ + 'verbose_name_plural': 'KPIs', + 'db_table': 'kpi', + 'ordering': ['-date'], + }, + ), + migrations.AddConstraint( + model_name='chickencounting', + constraint=models.UniqueConstraint(fields=('cycle', 'date'), name='uniq_chicken_counting_cycle_date'), + ), + migrations.AddConstraint( + model_name='chickenweight', + constraint=models.UniqueConstraint(fields=('cycle', 'date'), name='uniq_cw_cycle_date'), + ), + migrations.AddConstraint( + model_name='feedsacks', + constraint=models.UniqueConstraint(fields=('cycle', 'date'), name='uniq_feed_sacks_cycle_date'), + ), + migrations.AddConstraint( + model_name='iotpanel', + constraint=models.UniqueConstraint(fields=('flock', 'date'), name='uniq_iot_panel_flock_date'), + ), + migrations.AddConstraint( + model_name='manualinput', + constraint=models.UniqueConstraint(fields=('cycle', 'date'), name='uniq_manual_input_cycle_date'), + ), + migrations.AddConstraint( + model_name='kpi', + constraint=models.UniqueConstraint(fields=('cycle', 'date'), name='uniq_kpi_cycle_date'), + ), + ] diff --git a/backend/apps/operations/migrations/0002_harvest_weight_float.py b/backend/apps/operations/migrations/0002_harvest_weight_float.py new file mode 100644 index 0000000..40cb586 --- /dev/null +++ b/backend/apps/operations/migrations/0002_harvest_weight_float.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.17 on 2026-08-19 07:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('operations', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='kpi', + name='harvest_weight', + field=models.FloatField(default=0.0), + ), + migrations.AlterField( + model_name='kpi', + name='harvest_weight_total', + field=models.FloatField(default=0.0), + ), + migrations.AlterField( + model_name='manualinput', + name='harvest_weight_manual', + field=models.FloatField(default=0.0), + ), + migrations.AlterField( + model_name='manualinput', + name='harvest_weight_manual_total', + field=models.FloatField(default=0.0), + ), + ] diff --git a/backend/apps/operations/migrations/0003_erd_named_primary_keys.py b/backend/apps/operations/migrations/0003_erd_named_primary_keys.py new file mode 100644 index 0000000..8c09ea2 --- /dev/null +++ b/backend/apps/operations/migrations/0003_erd_named_primary_keys.py @@ -0,0 +1,18 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0005_erd_named_primary_keys"), + ("operations", "0002_harvest_weight_float"), + ] + + operations = [ + migrations.RenameField(model_name="iotpanel", old_name="id", new_name="panel_id"), + migrations.RenameField(model_name="feedsacks", old_name="id", new_name="fs_id"), + migrations.RenameField(model_name="chickencounting", old_name="id", new_name="cc_id"), + migrations.RenameField(model_name="chickenweight", old_name="id", new_name="cw_id"), + migrations.RenameField(model_name="manualinput", old_name="id", new_name="manual_id"), + migrations.RenameField(model_name="kpi", old_name="id", new_name="kpi_id"), + ] diff --git a/backend/apps/operations/migrations/0004_erd_column_updates.py b/backend/apps/operations/migrations/0004_erd_column_updates.py new file mode 100644 index 0000000..9ec4922 --- /dev/null +++ b/backend/apps/operations/migrations/0004_erd_column_updates.py @@ -0,0 +1,25 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("operations", "0003_erd_named_primary_keys"), + ] + + operations = [ + migrations.RenameField( + model_name="manualinput", + old_name="manual_weight_float", + new_name="manual_weight", + ), + migrations.RenameField( + model_name="kpi", + old_name="lot_weight", + new_name="iot_weight", + ), + migrations.AlterField( + model_name="chickenweight", + name="doc_weight", + field=models.FloatField(), + ), + ] diff --git a/backend/apps/operations/migrations/0005_erd_feed_and_doc_weight.py b/backend/apps/operations/migrations/0005_erd_feed_and_doc_weight.py new file mode 100644 index 0000000..248171f --- /dev/null +++ b/backend/apps/operations/migrations/0005_erd_feed_and_doc_weight.py @@ -0,0 +1,55 @@ +from django.db import migrations, models + + +def backfill_feed_in_from_feed_sacks(apps, schema_editor): + ManualInput = apps.get_model("operations", "ManualInput") + FeedSacks = apps.get_model("operations", "FeedSacks") + + feed_by_cycle_date = { + (fs.cycle_id, fs.date): fs + for fs in FeedSacks.objects.all().only("cycle_id", "date", "in_today", "in_total") + } + + for manual in ManualInput.objects.all().only("cycle_id", "date"): + fs = feed_by_cycle_date.get((manual.cycle_id, manual.date)) + if fs is None: + continue + manual.feed_in_manual = fs.in_today + manual.feed_in_manual_total = fs.in_total + manual.save(update_fields=["feed_in_manual", "feed_in_manual_total", "updated_at"]) + + +class Migration(migrations.Migration): + + dependencies = [ + ("operations", "0004_erd_column_updates"), + ] + + operations = [ + migrations.RenameField( + model_name="manualinput", + old_name="feed_manual", + new_name="feed_use_manual", + ), + migrations.RenameField( + model_name="manualinput", + old_name="feed_manual_total", + new_name="feed_use_manual_total", + ), + migrations.AddField( + model_name="manualinput", + name="feed_in_manual", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="manualinput", + name="feed_in_manual_total", + field=models.IntegerField(default=0), + ), + migrations.RunPython(backfill_feed_in_from_feed_sacks, migrations.RunPython.noop), + migrations.AlterField( + model_name="chickenweight", + name="doc_weight", + field=models.IntegerField(), + ), + ] diff --git a/backend/apps/operations/migrations/0006_iotpanel_timestamp.py b/backend/apps/operations/migrations/0006_iotpanel_timestamp.py new file mode 100644 index 0000000..b386593 --- /dev/null +++ b/backend/apps/operations/migrations/0006_iotpanel_timestamp.py @@ -0,0 +1,27 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0007_cycle_doc_in_weight_int"), + ("operations", "0005_erd_feed_and_doc_weight"), + ] + + operations = [ + migrations.RemoveConstraint( + model_name="iotpanel", + name="uniq_iot_panel_flock_date", + ), + migrations.AddField( + model_name="iotpanel", + name="timestamp", + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddConstraint( + model_name="iotpanel", + constraint=models.UniqueConstraint( + fields=("flock", "timestamp"), name="uniq_iot_panel_flock_timestamp" + ), + ), + ] \ No newline at end of file diff --git a/backend/apps/operations/migrations/0007_backfill_iotpanel_timestamp.py b/backend/apps/operations/migrations/0007_backfill_iotpanel_timestamp.py new file mode 100644 index 0000000..c77d8a5 --- /dev/null +++ b/backend/apps/operations/migrations/0007_backfill_iotpanel_timestamp.py @@ -0,0 +1,29 @@ +from datetime import datetime, time + +from django.db import migrations +from django.utils import timezone + + +def backfill_timestamps(apps, schema_editor): + IotPanel = apps.get_model("operations", "IotPanel") + for row in IotPanel.objects.filter(timestamp__isnull=True): + row.timestamp = timezone.make_aware( + datetime.combine(row.date, time(0, 0)), timezone.get_current_timezone() + ) + row.save(update_fields=["timestamp"]) + + +def unset_timestamps(apps, schema_editor): + IotPanel = apps.get_model("operations", "IotPanel") + IotPanel.objects.update(timestamp=None) + + +class Migration(migrations.Migration): + + dependencies = [ + ("operations", "0006_iotpanel_timestamp"), + ] + + operations = [ + migrations.RunPython(backfill_timestamps, unset_timestamps), + ] \ No newline at end of file diff --git a/backend/apps/operations/migrations/0008_manualinput_feed_out_manual.py b/backend/apps/operations/migrations/0008_manualinput_feed_out_manual.py new file mode 100644 index 0000000..dafb4ba --- /dev/null +++ b/backend/apps/operations/migrations/0008_manualinput_feed_out_manual.py @@ -0,0 +1,21 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("operations", "0007_backfill_iotpanel_timestamp"), + ] + + operations = [ + migrations.AddField( + model_name="manualinput", + name="feed_out_manual", + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name="manualinput", + name="feed_out_manual_total", + field=models.IntegerField(default=0), + ), + ] \ No newline at end of file diff --git a/backend/apps/operations/migrations/0009_reportsnapshot.py b/backend/apps/operations/migrations/0009_reportsnapshot.py new file mode 100644 index 0000000..c4b9589 --- /dev/null +++ b/backend/apps/operations/migrations/0009_reportsnapshot.py @@ -0,0 +1,61 @@ +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("farms", "0008_cycle_feed_initial_balance"), + ("operations", "0008_manualinput_feed_out_manual"), + ] + + operations = [ + migrations.CreateModel( + name="ReportSnapshot", + fields=[ + ( + "id", + models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID"), + ), + ( + "report_type", + models.CharField( + choices=[("daily", "Daily"), ("end_cycle", "End Cycle")], max_length=20 + ), + ), + ("up_to_day", models.IntegerField(default=0)), + ("payload", models.JSONField(default=dict)), + ("generated_at", models.DateTimeField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "cycle", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="report_snapshots", + to="farms.cycle", + ), + ), + ( + "kandang", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="report_snapshots", + to="farms.kandang", + ), + ), + ], + options={ + "verbose_name": "Report Snapshot", + "verbose_name_plural": "Report Snapshots", + "db_table": "report_snapshot", + "ordering": ["-updated_at"], + "constraints": [ + models.UniqueConstraint( + fields=("cycle", "kandang", "report_type"), + name="uniq_report_snapshot_cycle_kandang_type", + ) + ], + }, + ), + ] \ No newline at end of file diff --git a/backend/apps/operations/migrations/0010_delete_reportsnapshot.py b/backend/apps/operations/migrations/0010_delete_reportsnapshot.py new file mode 100644 index 0000000..04f509f --- /dev/null +++ b/backend/apps/operations/migrations/0010_delete_reportsnapshot.py @@ -0,0 +1,14 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("operations", "0009_reportsnapshot"), + ] + + operations = [ + migrations.DeleteModel( + name="ReportSnapshot", + ), + ] \ No newline at end of file diff --git a/backend/apps/operations/migrations/__init__.py b/backend/apps/operations/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/operations/models.py b/backend/apps/operations/models.py new file mode 100644 index 0000000..b3362e2 --- /dev/null +++ b/backend/apps/operations/models.py @@ -0,0 +1,170 @@ +from django.db import models + +from apps.farms.models import Cycle, Flock + + +class IotPanel(models.Model): + panel_id = models.BigAutoField(primary_key=True) + date = models.DateField() + timestamp = models.DateTimeField(null=True, blank=True) + wind_speed = models.FloatField(default=0.0) + humidity = models.FloatField(default=0.0) + water_total = models.FloatField(default=0.0) + average_temperature = models.FloatField(default=0.0) + experience_temperature = models.FloatField(default=0.0) + flock = models.ForeignKey(Flock, on_delete=models.CASCADE, related_name="iot_panels") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "iot_panel" + ordering = ["-date"] + verbose_name = "IoT Panel" + verbose_name_plural = "IoT Panels" + constraints = [ + models.UniqueConstraint(fields=["flock", "timestamp"], name="uniq_iot_panel_flock_timestamp") + ] + + +class AIInsight(models.Model): + date = models.DateField() + insight_text = models.TextField() + alert = models.CharField(max_length=100) + section = models.CharField(max_length=100) + session = models.CharField(max_length=100) + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="ai_insights") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "ai_insight" + ordering = ["-date"] + + +class FeedSacks(models.Model): + fs_id = models.BigAutoField(primary_key=True) + date = models.DateField() + in_today = models.IntegerField(default=0) + out_today = models.IntegerField(default=0) + in_total = models.IntegerField(default=0) + out_total = models.IntegerField(default=0) + feed_use_today = models.IntegerField(default=0) + feed_use_total = models.IntegerField(default=0) + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="feed_sacks") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "feed_sacks" + ordering = ["-date"] + verbose_name_plural = "Feed sacks" + constraints = [ + models.UniqueConstraint(fields=["cycle", "date"], name="uniq_feed_sacks_cycle_date") + ] + + +class ChickenCounting(models.Model): + cc_id = models.BigAutoField(primary_key=True) + date = models.DateField() + total_count = models.IntegerField(default=0) + mortality_count = models.IntegerField(default=0) + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="chicken_countings") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "chicken_counting" + ordering = ["-date"] + constraints = [ + models.UniqueConstraint(fields=["cycle", "date"], name="uniq_chicken_counting_cycle_date") + ] + + +class ChickenWeight(models.Model): + cw_id = models.BigAutoField(primary_key=True) + date = models.DateField() + age = models.IntegerField() + doc_weight = models.IntegerField() + average_weight = models.FloatField() + chicken_count = models.IntegerField() + uniformity = models.FloatField() + average_daily_gain = models.FloatField() + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="chicken_weights") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "chicken_weight" + ordering = ["-date"] + constraints = [ + models.UniqueConstraint(fields=["cycle", "date"], name="uniq_cw_cycle_date") + ] + + +class ManualInput(models.Model): + manual_id = models.BigAutoField(primary_key=True) + date = models.DateField() + age_manual = models.IntegerField(default=0) + mortality_manual = models.IntegerField(default=0) + mortality_manual_total = models.IntegerField(default=0) + feed_in_manual = models.IntegerField(default=0) + feed_use_manual = models.IntegerField(default=0) + feed_in_manual_total = models.IntegerField(default=0) + feed_use_manual_total = models.IntegerField(default=0) + feed_out_manual = models.IntegerField(default=0) + feed_out_manual_total = models.IntegerField(default=0) + harvest_manual = models.IntegerField(default=0) + harvest_manual_total = models.IntegerField(default=0) + harvest_weight_manual = models.FloatField(default=0.0) + harvest_weight_manual_total = models.FloatField(default=0.0) + manual_weight = models.FloatField(default=0.0) + average_harvest_day_manual = models.FloatField(default=0.0) + average_harvest_weight_manual = models.FloatField(default=0.0) + fcr_manual = models.FloatField(default=0.0) + eef_manual = models.FloatField(default=0.0) + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="manual_inputs") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "manual_input" + ordering = ["-date"] + constraints = [ + models.UniqueConstraint(fields=["cycle", "date"], name="uniq_manual_input_cycle_date") + ] + + +class KPI(models.Model): + kpi_id = models.BigAutoField(primary_key=True) + date = models.DateField() + age = models.IntegerField(default=0) + mortality = models.IntegerField(default=0) + mortality_total = models.IntegerField(default=0) + feed = models.IntegerField(default=0) + feed_total = models.IntegerField(default=0) + harvest = models.IntegerField(default=0) + harvest_total = models.IntegerField(default=0) + harvest_weight = models.FloatField(default=0.0) + harvest_weight_total = models.FloatField(default=0.0) + chicken_life = models.IntegerField(default=0) + chicken_life_percentage = models.FloatField(default=0.0) + iot_weight = models.FloatField(default=0.0) + average_harvest_day = models.FloatField(default=0.0) + average_harvest_weight = models.FloatField(default=0.0) + fcr = models.FloatField(default=0.0) + eef = models.FloatField(default=0.0) + cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="kpis") + cc = models.ForeignKey(ChickenCounting, on_delete=models.RESTRICT, related_name="kpis") + cw = models.ForeignKey(ChickenWeight, on_delete=models.RESTRICT, related_name="kpis") + fs = models.ForeignKey(FeedSacks, on_delete=models.RESTRICT, related_name="kpis") + manual = models.ForeignKey(ManualInput, on_delete=models.RESTRICT, related_name="kpis") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "kpi" + ordering = ["-date"] + verbose_name_plural = "KPIs" + constraints = [ + models.UniqueConstraint(fields=["cycle", "date"], name="uniq_kpi_cycle_date") + ] diff --git a/backend/apps/operations/serializers.py b/backend/apps/operations/serializers.py new file mode 100644 index 0000000..17a68bb --- /dev/null +++ b/backend/apps/operations/serializers.py @@ -0,0 +1,138 @@ +from django.db import transaction +from rest_framework import serializers + +from apps.operations.models import ( + AIInsight, + ChickenCounting, + ChickenWeight, + FeedSacks, + IotPanel, + KPI, + ManualInput, +) +from apps.accounts.serializers import PkAsIdMixin +from apps.operations.services.manual_input import recompute_manual_totals + + +class CycleContextMixin(serializers.Serializer): + kandang = serializers.IntegerField(source="cycle.kandang_id", read_only=True) + flock_id = serializers.SerializerMethodField() + + def get_flock_id(self, obj): + flock = obj.cycle.kandang.flocks.order_by("flock_id").first() + return flock.pk if flock is not None else None + + +class KPISerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = KPI + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] + + +class ManualInputSerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = ManualInput + fields = "__all__" + read_only_fields = [ + "id", + "created_at", + "updated_at", + "mortality_manual_total", + "feed_in_manual_total", + "feed_use_manual_total", + "feed_out_manual_total", + "harvest_manual_total", + "harvest_weight_manual_total", + "average_harvest_day_manual", + "average_harvest_weight_manual", + "fcr_manual", + "eef_manual", + ] + validators = [] + + def create(self, validated_data): + return self._upsert(validated_data) + + def update(self, instance, validated_data): + validated_data.setdefault("cycle", instance.cycle) + validated_data.setdefault("date", instance.date) + return self._upsert(validated_data, instance=instance) + + def _upsert(self, validated_data, instance=None): + cycle = validated_data.get("cycle") or (instance.cycle if instance else None) + row_date = validated_data.get("date") or (instance.date if instance else None) + defaults = { + "age_manual": validated_data.get("age_manual", instance.age_manual if instance else 0), + "mortality_manual": validated_data.get( + "mortality_manual", instance.mortality_manual if instance else 0 + ), + "feed_in_manual": validated_data.get( + "feed_in_manual", instance.feed_in_manual if instance else 0 + ), + "feed_use_manual": validated_data.get( + "feed_use_manual", instance.feed_use_manual if instance else 0 + ), + "feed_out_manual": validated_data.get( + "feed_out_manual", instance.feed_out_manual if instance else 0 + ), + "harvest_manual": validated_data.get( + "harvest_manual", instance.harvest_manual if instance else 0 + ), + "harvest_weight_manual": validated_data.get( + "harvest_weight_manual", instance.harvest_weight_manual if instance else 0 + ), + "manual_weight": validated_data.get( + "manual_weight", instance.manual_weight if instance else 0.0 + ), + } + with transaction.atomic(): + row, _created = ManualInput.objects.update_or_create( + cycle=cycle, + date=row_date, + defaults=defaults, + ) + recompute_manual_totals(cycle) + row.refresh_from_db() + return row + + +class ChickenCountingSerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = ChickenCounting + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] + + +class ChickenWeightSerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = ChickenWeight + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] + + +class FeedSacksSerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = FeedSacks + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] + + +class IotPanelSerializer(PkAsIdMixin, serializers.ModelSerializer): + kandang = serializers.SerializerMethodField() + flock_id = serializers.IntegerField(read_only=True) + + class Meta: + model = IotPanel + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] + + def get_kandang(self, obj): + return obj.flock.kandang_id + + +class AIInsightSerializer(PkAsIdMixin, CycleContextMixin, serializers.ModelSerializer): + class Meta: + model = AIInsight + fields = "__all__" + read_only_fields = ["id", "created_at", "updated_at"] diff --git a/backend/apps/operations/services/__init__.py b/backend/apps/operations/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/operations/services/chicken_counting_edge.py b/backend/apps/operations/services/chicken_counting_edge.py new file mode 100644 index 0000000..432b1a0 --- /dev/null +++ b/backend/apps/operations/services/chicken_counting_edge.py @@ -0,0 +1,214 @@ +from __future__ import annotations + +import re +from datetime import date +from typing import Any +from urllib.parse import urljoin + +import httpx +from django.conf import settings +from django.core.exceptions import ValidationError +from django.db import transaction +from django.utils import timezone + +from apps.farms.models import Cycle +from apps.operations.models import ChickenCounting + + +class ChickenCountingEdgeError(Exception): + def __init__(self, message: str, status_code: int | None = None): + super().__init__(message) + self.status_code = status_code + + +def kandang_index(kandang_name: str) -> str: + match = re.search(r"(\d+)", kandang_name or "") + if not match: + raise ValidationError( + f"Cannot derive edge kandang index from kandang name: {kandang_name!r}" + ) + return match.group(1) + + +def location_prefix_for_kandang(kandang_name: str) -> str: + """``Kandang 1`` → ``K1`` (matches floor prefixes like ``K1-L1``).""" + return f"K{kandang_index(kandang_name)}" + + +def coop_for_kandang(kandang_name: str) -> str: + """``Kandang 1`` → ``K1`` (mortality ``coop`` field).""" + return location_prefix_for_kandang(kandang_name) + + +def _parse_history_date(raw: Any) -> date | None: + if raw is None: + return None + try: + return date.fromisoformat(str(raw)[:10]) + except ValueError: + return None + + +def aggregate_counting_by_date( + rows: list[dict[str, Any]] | None, + *, + kandang_name: str, +) -> dict[date, int]: + """Sum ``total`` for floors whose location starts with ``KN-`` / equals ``KN``.""" + prefix = location_prefix_for_kandang(kandang_name) + by_date: dict[date, int] = {} + for row in rows or []: + day = _parse_history_date(row.get("date")) + if day is None: + continue + location = str(row.get("location") or "").strip() + if location != prefix and not location.startswith(f"{prefix}-"): + continue + by_date[day] = by_date.get(day, 0) + int(row.get("total") or 0) + return by_date + + +def aggregate_mortality_by_date( + rows: list[dict[str, Any]] | None, + *, + kandang_name: str, +) -> dict[date, int]: + """Map date → ``total_mortality_count`` for the matching coop.""" + expected = coop_for_kandang(kandang_name).casefold() + by_date: dict[date, int] = {} + for row in rows or []: + day = _parse_history_date(row.get("date")) + if day is None: + continue + coop = str(row.get("coop") or row.get("location") or "").strip() + if coop.casefold() != expected: + continue + by_date[day] = int(row.get("total_mortality_count") or 0) + return by_date + + +def cycle_history_window(cycle: Cycle, *, today: date | None = None) -> tuple[date, date]: + if today is None: + today = timezone.localdate() + end = min(today, cycle.end_date) + return cycle.start_date, end + + +class ChickenCountingEdgeClient: + """Outbound client for the chicken-counting edge box.""" + + DB_HISTORY_PATH = "/api/db/history" + MORTALITY_HISTORY_PATH = "/api/mortality/history" + + def __init__(self, base_url: str | None = None, timeout: float | None = None): + self.base_url = ( + base_url or getattr(settings, "CHICKEN_COUNTING_EDGE_BASE_URL", "") or "" + ).rstrip("/") + self.timeout = timeout or float( + getattr(settings, "CHICKEN_COUNTING_EDGE_TIMEOUT_SECONDS", 30) or 30 + ) + + def _get_json(self, path: str) -> Any: + if not self.base_url: + raise ChickenCountingEdgeError("CHICKEN_COUNTING_EDGE_BASE_URL is not configured") + url = urljoin(self.base_url + "/", path.lstrip("/")) + try: + with httpx.Client(timeout=self.timeout) as client: + response = client.get(url) + except httpx.HTTPError as exc: + raise ChickenCountingEdgeError(f"chicken counting edge request failed: {exc}") from exc + if response.status_code >= 400: + raise ChickenCountingEdgeError( + f"chicken counting edge HTTP {response.status_code}: {response.text[:300]}", + status_code=response.status_code, + ) + return response.json() + + def fetch_db_history(self) -> list[dict[str, Any]]: + payload = self._get_json(self.DB_HISTORY_PATH) + if isinstance(payload, list): + return payload + return list(payload.get("results") or payload.get("history") or []) + + def fetch_mortality_history(self) -> list[dict[str, Any]]: + payload = self._get_json(self.MORTALITY_HISTORY_PATH) + if isinstance(payload, list): + return payload + return list(payload.get("results") or payload.get("history") or []) + + +@transaction.atomic +def sync_chicken_counting_for_cycle( + cycle: Cycle, + *, + db_history: list[dict[str, Any]] | None = None, + mortality_history: list[dict[str, Any]] | None = None, +) -> dict[str, Any]: + """Upsert ChickenCounting from edge history within the cycle window.""" + counting_enabled = bool( + getattr(settings, "CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED", True) + ) + mortality_enabled = bool( + getattr(settings, "CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED", True) + ) + if not counting_enabled and not mortality_enabled: + return {"dates": [], "upserted": 0, "skipped": True} + + client = ChickenCountingEdgeClient() + if db_history is None and counting_enabled: + db_history = client.fetch_db_history() + if mortality_history is None and mortality_enabled: + mortality_history = client.fetch_mortality_history() + + kandang_name = cycle.kandang.kandang_name + counting_by_date = ( + aggregate_counting_by_date(db_history, kandang_name=kandang_name) + if counting_enabled + else {} + ) + mortality_by_date = ( + aggregate_mortality_by_date(mortality_history, kandang_name=kandang_name) + if mortality_enabled + else {} + ) + + start, end = cycle_history_window(cycle) + dates = sorted(set(counting_by_date) | set(mortality_by_date)) + upserted: list[date] = [] + + for day in dates: + if day < start or day > end: + continue + defaults: dict[str, int] = {} + if counting_enabled and day in counting_by_date: + defaults["total_count"] = counting_by_date[day] + if mortality_enabled and day in mortality_by_date: + defaults["mortality_count"] = mortality_by_date[day] + if not defaults: + continue + + obj, created = ChickenCounting.objects.get_or_create( + cycle=cycle, + date=day, + defaults={ + "total_count": defaults.get("total_count", 0), + "mortality_count": defaults.get("mortality_count", 0), + }, + ) + if not created: + update_fields = [] + if "total_count" in defaults and obj.total_count != defaults["total_count"]: + obj.total_count = defaults["total_count"] + update_fields.append("total_count") + if ( + "mortality_count" in defaults + and obj.mortality_count != defaults["mortality_count"] + ): + obj.mortality_count = defaults["mortality_count"] + update_fields.append("mortality_count") + if update_fields: + update_fields.append("updated_at") + obj.save(update_fields=update_fields) + upserted.append(day) + + return {"dates": upserted, "upserted": len(upserted), "skipped": False} diff --git a/backend/apps/operations/services/feed_sacks.py b/backend/apps/operations/services/feed_sacks.py new file mode 100644 index 0000000..13d71e4 --- /dev/null +++ b/backend/apps/operations/services/feed_sacks.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +from datetime import date + +from apps.farms.models import Cycle +from apps.operations.models import FeedSacks + + +def recompute_feed_sack_in_totals(cycle: Cycle) -> None: + """Rebuild cumulative in_total from daily IoT feed-in only (excludes opening balance).""" + running = 0 + for fs_row in FeedSacks.objects.filter(cycle=cycle).order_by("date", "pk"): + running += fs_row.in_today + if fs_row.in_total != running: + fs_row.in_total = running + fs_row.save(update_fields=["in_total", "updated_at"]) + + +def remove_opening_balance_feed_row( + cycle: Cycle, + *, + balance_date: date | None, + balance_amount: int, +) -> None: + """Drop a FeedSacks row that only existed to carry opening balance.""" + if balance_date is None or balance_amount <= 0: + return + FeedSacks.objects.filter( + cycle=cycle, + date=balance_date, + in_today=balance_amount, + out_today=0, + feed_use_today=0, + out_total=0, + feed_use_total=0, + ).delete() + + +def cleanup_opening_balance_feed_rows( + cycle: Cycle, + *, + previous_date: date | None, + previous_balance: int, + balance_date: date, + balance_amount: int, +) -> None: + """Remove opening-balance snapshot rows for the previous and current save.""" + for row_date, amount in ( + (previous_date, previous_balance), + (balance_date, balance_amount), + ): + remove_opening_balance_feed_row( + cycle, + balance_date=row_date, + balance_amount=amount, + ) + + # Legacy cleanup: drop opening-only rows left from earlier saves on other dates. + opening_amounts = { + amount for amount in (previous_balance, balance_amount) if amount > 0 + } + if not opening_amounts: + return + FeedSacks.objects.filter( + cycle=cycle, + in_today__in=opening_amounts, + out_today=0, + feed_use_today=0, + out_total=0, + feed_use_total=0, + ).delete() diff --git a/backend/apps/operations/services/iot_api.py b/backend/apps/operations/services/iot_api.py new file mode 100644 index 0000000..c9715e3 --- /dev/null +++ b/backend/apps/operations/services/iot_api.py @@ -0,0 +1,264 @@ +"""Sync IoT panel readings from dashboard.cpsp.id/api/iot/flocks/ (10-minute snapshots).""" + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import date, datetime, timedelta, timezone as dt_timezone +from typing import Any +from zoneinfo import ZoneInfo + +import httpx +from django.conf import settings +from django.utils import timezone + +from apps.farms.models import Cycle, Flock +from apps.operations.models import IotPanel + +WIB = ZoneInfo("Asia/Jakarta") + +CHILL_FACTOR_POINTS = ( + (0, 8.0), + (1, 8.0), + (7, 7.0), + (14, 6.0), + (21, 4.5), + (28, 3.5), + (35, 3.5), + (42, 3.0), +) + + +class IotApiError(Exception): + def __init__(self, message: str, status_code: int | None = None): + super().__init__(message) + self.status_code = status_code + + +def _sensor_celsius(sensor: dict | float | int | None) -> float | None: + if sensor is None: + return None + if isinstance(sensor, (int, float)): + return float(sensor) + raw = sensor.get("value") + if raw is None: + return None + cal = float(sensor.get("calibration") or 0) + return (float(raw) + cal) / 10.0 + + +def _sensor_humidity_pct(sensor: dict | float | int | None, fallback: float | None) -> float: + if isinstance(sensor, dict): + raw = sensor.get("value") + if raw is not None: + cal = float(sensor.get("calibration") or 0) + return (float(raw) + cal) / 10.0 + if isinstance(sensor, (int, float)): + return float(sensor) + if fallback is None: + return 70.0 + value = float(fallback) + return value / 10.0 if value > 100 else value + + +def _wind_ms(payload_wind: float | int | None, sensors_wind: dict | float | int | None) -> float: + if isinstance(sensors_wind, dict) and sensors_wind.get("value") is not None: + return float(sensors_wind["value"]) / 10.0 + if isinstance(sensors_wind, (int, float)): + return float(sensors_wind) + if payload_wind is None: + return 0.0 + return float(payload_wind) / 10.0 + + +def _average_inside_temp_c(sensors: dict | None, actual_temperature: float | int | None) -> float: + if sensors: + readings = [ + v + for v in ( + _sensor_celsius(sensors.get("temperature1")), + _sensor_celsius(sensors.get("temperature2")), + _sensor_celsius(sensors.get("temperature3")), + ) + if v is not None + ] + if readings: + return sum(readings) / len(readings) + if actual_temperature is None: + return 0.0 + value = float(actual_temperature) + return value / 10.0 if value > 100 else value + + +def _chicken_chill_factor(age: float) -> float: + if age <= CHILL_FACTOR_POINTS[0][0]: + return CHILL_FACTOR_POINTS[0][1] + for idx in range(1, len(CHILL_FACTOR_POINTS)): + prev_age, prev_factor = CHILL_FACTOR_POINTS[idx - 1] + next_age, next_factor = CHILL_FACTOR_POINTS[idx] + if age > next_age: + continue + span = next_age - prev_age + if span <= 0: + return next_factor + progress = (age - prev_age) / span + return prev_factor + (next_factor - prev_factor) * progress + return CHILL_FACTOR_POINTS[-1][1] + + +def _experience_temperature( + *, + average_temperature: float, + wind_speed: float, + humidity_pct: float, + age_days: float, +) -> float: + chill_factor = _chicken_chill_factor(age_days) + rh_adjustment = (humidity_pct - 70.0) / 5.0 + chill_effect = wind_speed * chill_factor - rh_adjustment + return average_temperature - chill_effect + + +def panel_fields_from_payload(data: dict, age_days: int) -> dict[str, float]: + sensors = data.get("sensors") or {} + humidity = _sensor_humidity_pct(sensors.get("humidity"), data.get("humidity")) + wind_speed = _wind_ms(data.get("wind"), sensors.get("wind")) + avg_temp = _average_inside_temp_c(sensors, data.get("actualTemperature")) + water = data.get("water") + if water is None and isinstance(sensors.get("water"), dict): + water = sensors["water"].get("value") + return { + "wind_speed": round(wind_speed, 4), + "humidity": round(humidity, 4), + "water_total": float(water or 0), + "average_temperature": round(avg_temp, 4), + "experience_temperature": round( + _experience_temperature( + average_temperature=avg_temp, + wind_speed=wind_speed, + humidity_pct=humidity, + age_days=age_days, + ), + 4, + ), + } + + +def parse_fetched_at(value: str) -> datetime: + parsed = datetime.fromisoformat(value.replace("Z", "+00:00")) + if timezone.is_naive(parsed): + return timezone.make_aware(parsed, dt_timezone.utc) + return parsed + + +def cycle_age_for_date(cycle_start: date, snapshot_date: date) -> int: + if snapshot_date < cycle_start: + return 1 + return (snapshot_date - cycle_start).days + 1 + + +@dataclass +class SyncSummary: + upserted: int + skipped: int + pages: int + + +class IotApiClient: + def __init__(self, base_url: str | None = None, timeout: float | None = None): + self.base_url = (base_url or settings.IOT_API_BASE_URL).rstrip("/") + "/" + self.timeout = timeout or settings.IOT_API_SYNC_TIMEOUT_SECONDS + + def fetch_page(self, page: int) -> dict[str, Any]: + url = f"{self.base_url}?page={page}" + try: + with httpx.Client(timeout=self.timeout) as client: + response = client.get(url) + except httpx.HTTPError as exc: + raise IotApiError(f"IoT API request failed: {exc}") from exc + if response.status_code >= 400: + raise IotApiError( + f"IoT API HTTP {response.status_code}: {response.text[:300]}", + status_code=response.status_code, + ) + return response.json() + + +def sync_iot_panels( + *, + lookback_minutes: int | None = None, + max_pages: int | None = None, +) -> SyncSummary: + flock_map: dict[str, int] = getattr(settings, "IOT_FLOCK_ID_MAP", {}) or {} + if not flock_map: + return SyncSummary(upserted=0, skipped=0, pages=0) + + lookback = lookback_minutes if lookback_minutes is not None else settings.IOT_SYNC_LOOKBACK_MINUTES + page_limit = max_pages if max_pages is not None else settings.IOT_SYNC_MAX_PAGES + cutoff = timezone.now() - timedelta(minutes=lookback) + + django_flocks: dict[str, Flock] = {} + for external_id, django_id in flock_map.items(): + try: + django_flocks[str(external_id)] = Flock.objects.select_related("kandang").get(pk=int(django_id)) + except Flock.DoesNotExist: + continue + + client = IotApiClient() + upserted = 0 + skipped = 0 + pages_read = 0 + + for page in range(1, page_limit + 1): + payload = client.fetch_page(page) + pages_read += 1 + results = payload.get("results") or [] + if not results: + break + + page_has_recent = False + for record in results: + external_flock_id = str(record.get("flock_id") or "") + flock = django_flocks.get(external_flock_id) + if flock is None: + skipped += 1 + continue + + fetched_raw = record.get("fetched_at") + payload_data = (record.get("payload") or {}).get("data") + if not fetched_raw or not payload_data: + skipped += 1 + continue + + fetched_at = parse_fetched_at(fetched_raw) + if fetched_at >= cutoff: + page_has_recent = True + elif page > 1: + continue + + snapshot_date = fetched_at.astimezone(WIB).date() + cycle = ( + Cycle.objects.filter( + kandang_id=flock.kandang_id, + start_date__lte=snapshot_date, + end_date__gte=snapshot_date, + ) + .order_by("-start_date") + .first() + ) + age = cycle_age_for_date(cycle.start_date, snapshot_date) if cycle else 1 + fields = panel_fields_from_payload(payload_data, age) + + IotPanel.objects.update_or_create( + flock=flock, + timestamp=fetched_at, + defaults={ + "date": snapshot_date, + **fields, + }, + ) + upserted += 1 + + if not page_has_recent and page > 1: + break + + return SyncSummary(upserted=upserted, skipped=skipped, pages=pages_read) diff --git a/backend/apps/operations/services/karung_web.py b/backend/apps/operations/services/karung_web.py new file mode 100644 index 0000000..618a091 --- /dev/null +++ b/backend/apps/operations/services/karung_web.py @@ -0,0 +1,334 @@ +from __future__ import annotations + +import re +from datetime import date +from typing import Any +from urllib.parse import urljoin + +import httpx +from django.conf import settings +from django.core.exceptions import ValidationError +from django.utils import timezone + +from apps.farms.models import Cycle +from apps.operations.models import FeedSacks + + +class KarungWebError(Exception): + def __init__(self, message: str, status_code: int | None = None): + super().__init__(message) + self.status_code = status_code + + +def kandang_index(kandang_name: str) -> str: + """Extract the numeric kandang index from labels like ``Kandang 1``.""" + match = re.search(r"(\d+)", kandang_name or "") + if not match: + raise ValidationError( + f"Cannot derive IoT kandang index from kandang name: {kandang_name!r}" + ) + return match.group(1) + + +def source_for_kandang(kandang_name: str, *, kind: str) -> str: + """Map a kandang label to a karung-web-admin source such as ``K1 - In``.""" + return f"K{kandang_index(kandang_name)} - {kind}" + + +def masuk_source_for_kandang(kandang_name: str) -> str: + """Map a kandang label like ``Kandang 1`` to the karung-web-admin source ``K1 - In``.""" + return source_for_kandang(kandang_name, kind="In") + + +def _karung_for_source(rows: list[dict[str, Any]] | None, expected_source: str) -> int: + normalized = _normalize_source(expected_source) + for row in rows or []: + if _normalize_source(row.get("source")) == normalized: + return int(row.get("karung") or row.get("counter_value") or 0) + return 0 + + +def _normalize_source(value: str | None) -> str: + return (value or "").strip().casefold() + + +def _parse_history_date(raw: Any) -> date | None: + if raw is None: + return None + try: + return date.fromisoformat(str(raw)[:10]) + except ValueError: + return None + + +def daily_totals_from_combined_history( + combined: dict[str, Any], + *, + kandang_name: str, +) -> dict[date, dict[str, int]]: + """Group /api/combined history into per-date in/out/use for one kandang.""" + in_source = _normalize_source(source_for_kandang(kandang_name, kind="In")) + out_source = _normalize_source(source_for_kandang(kandang_name, kind="Out")) + use_source = _normalize_source(source_for_kandang(kandang_name, kind="Use")) + + by_date: dict[date, dict[str, int]] = {} + + def ensure(day: date) -> dict[str, int]: + return by_date.setdefault( + day, {"in_today": 0, "out_today": 0, "feed_use_today": 0} + ) + + masuk_history = (combined.get("masuk") or {}).get("history") or [] + for row in masuk_history: + day = _parse_history_date(row.get("date")) + if day is None: + continue + source = _normalize_source(row.get("source")) + value = int(row.get("counter_value") or row.get("karung") or 0) + if source == in_source: + ensure(day)["in_today"] = value + elif source == out_source: + ensure(day)["out_today"] = value + + tuang_history = (combined.get("tuang") or {}).get("history") or [] + for row in tuang_history: + day = _parse_history_date(row.get("date")) + if day is None: + continue + source = _normalize_source(row.get("source")) + value = int(row.get("counter_value") or row.get("karung") or 0) + if source == use_source: + ensure(day)["feed_use_today"] = value + + return by_date + + +def cycle_history_window(cycle: Cycle, *, today: date | None = None) -> tuple[date, date]: + """Inclusive date window for history upserts.""" + if today is None: + today = timezone.localdate() + end = min(today, cycle.end_date) + return cycle.start_date, end + + +def backfill_karung_from_combined( + cycle: Cycle, + combined: dict[str, Any] | None = None, +) -> list[date]: + """Upsert FeedSacks for cycle dates present in combined history. Returns upserted dates.""" + if combined is None: + combined = KarungWebClient().fetch_combined() + + kandang_name = cycle.kandang.kandang_name + by_date = daily_totals_from_combined_history(combined, kandang_name=kandang_name) + start, end = cycle_history_window(cycle) + upserted: list[date] = [] + + for day in sorted(by_date): + if day < start or day > end: + continue + totals = by_date[day] + FeedSacks.objects.update_or_create( + cycle=cycle, + date=day, + defaults={ + "in_today": totals["in_today"], + "out_today": totals["out_today"], + "feed_use_today": totals["feed_use_today"], + }, + ) + upserted.append(day) + return upserted + + +def recompute_feed_sack_totals(cycle: Cycle) -> None: + """Recompute running in/out/use totals for all FeedSacks of a cycle in date order.""" + running_in = 0 + running_out = 0 + running_use = 0 + rows = list(FeedSacks.objects.filter(cycle=cycle).order_by("date", "pk")) + for row in rows: + running_in += row.in_today or 0 + running_out += row.out_today or 0 + running_use += row.feed_use_today or 0 + changed = ( + row.in_total != running_in + or row.out_total != running_out + or row.feed_use_total != running_use + ) + if changed: + row.in_total = running_in + row.out_total = running_out + row.feed_use_total = running_use + row.save(update_fields=["in_total", "out_total", "feed_use_total", "updated_at"]) + + +class KarungWebClient: + """Outbound client for karung-web-admin — base URL from settings only.""" + + SECTIONS_PATH = "/api/v1/cycles/active/sections" + COMBINED_PATH = "/api/combined" + + def __init__(self, base_url: str | None = None, timeout: float | None = None): + self.base_url = (base_url or settings.KARUNG_WEB_ADMIN_BASE_URL).rstrip("/") + self.timeout = timeout or settings.KARUNG_WEB_ADMIN_TIMEOUT_SECONDS + + def _get_json(self, path: str) -> dict[str, Any]: + if not self.base_url: + raise KarungWebError("KARUNG_WEB_ADMIN_BASE_URL is not configured") + url = urljoin(self.base_url + "/", path.lstrip("/")) + try: + with httpx.Client(timeout=self.timeout) as client: + response = client.get(url) + except httpx.HTTPError as exc: + raise KarungWebError(f"karung-web-admin request failed: {exc}") from exc + if response.status_code >= 400: + raise KarungWebError( + f"karung-web-admin HTTP {response.status_code}: {response.text[:300]}", + status_code=response.status_code, + ) + payload = response.json() + if not payload.get("success", True) and payload.get("error"): + error = payload.get("error") or {} + raise KarungWebError(error.get("message") or "karung-web-admin returned failure") + return payload.get("data") or payload + + def fetch_active_sections(self) -> dict[str, Any]: + return self._get_json(self.SECTIONS_PATH) + + def fetch_combined(self) -> dict[str, Any]: + return self._get_json(self.COMBINED_PATH) + + +def fetch_iot_masuk_for_date(target_date: date, *, kandang_name: str) -> int | None: + """Return IoT karung-masuk for ``target_date`` and kandang from karung-web-admin /api/combined.""" + expected_source = _normalize_source(masuk_source_for_kandang(kandang_name)) + target = target_date.isoformat() + + client = KarungWebClient() + data = client.fetch_combined() + masuk = data.get("masuk") or {} + + for row in masuk.get("history") or []: + if row.get("date") == target and _normalize_source(row.get("source")) == expected_source: + return int(row.get("counter_value") or 0) + + if target_date == date.today(): + for row in masuk.get("today") or []: + if _normalize_source(row.get("source")) == expected_source: + return int(row.get("karung") or 0) + + return None + + +def initial_balance_accuracy(manual: int, iot_in: int | None) -> float | None: + if manual > 0 and iot_in is not None and iot_in > 0: + return round(min(manual, iot_in) / max(manual, iot_in) * 1000) / 10 + if manual == 0 and iot_in == 0: + return 100.0 + return None + + +def pull_initial_balance_iot(cycle: Cycle, balance_date: date) -> tuple[int | None, str | None]: + sync_error = None + iot_in = None + try: + iot_in = fetch_iot_masuk_for_date( + balance_date, + kandang_name=cycle.kandang.kandang_name, + ) + except KarungWebError as exc: + sync_error = str(exc) + return iot_in, sync_error + + +def request_karung( + cycle: Cycle, + *, + section: str = "today", +) -> tuple[FeedSacks, dict[str, Any]]: + if section not in {"today", "yesterday_history"}: + raise ValidationError("section must be today or yesterday_history") + + client = KarungWebClient() + data = client.fetch_active_sections() + sections = data.get("sections") or {} + block = sections.get(section) or {} + totals = block.get("totals") or {} + remote_cycle = data.get("cycle") or {} + kandang_name = cycle.kandang.kandang_name + k_index = kandang_index(kandang_name) + masuk_rows = block.get("masuk") or [] + tuang_rows = block.get("tuang") or [] + + in_today = _karung_for_source(masuk_rows, f"K{k_index} - In") + feed_use_today = _karung_for_source(tuang_rows, f"K{k_index} - Use") + out_today = _karung_for_source(masuk_rows, f"K{k_index} - Out") + saldo_awal = int(remote_cycle.get("saldo_awal") or 0) + + snapshot_raw = block.get("date") + snapshot_date = date.fromisoformat(str(snapshot_raw)) if snapshot_raw else timezone.localdate() + + prior = ( + FeedSacks.objects.filter(cycle=cycle) + .exclude(date=snapshot_date) + .order_by("-date", "-pk") + .first() + ) + if prior: + in_total = prior.in_total + in_today + out_total = prior.out_total + out_today + feed_use_total = prior.feed_use_total + feed_use_today + else: + in_total = in_today + out_total = out_today + feed_use_total = feed_use_today + + feed_sack, _ = FeedSacks.objects.update_or_create( + cycle=cycle, + date=snapshot_date, + defaults={ + "in_today": in_today, + "out_today": out_today, + "in_total": in_total, + "out_total": out_total, + "feed_use_today": feed_use_today, + "feed_use_total": feed_use_total, + }, + ) + summary = { + "section": section, + "snapshot_date": snapshot_date.isoformat(), + "totals": totals, + "kandang": kandang_name, + "kandang_sources": { + "in": source_for_kandang(kandang_name, kind="In"), + "use": source_for_kandang(kandang_name, kind="Use"), + "out": source_for_kandang(kandang_name, kind="Out"), + }, + "kandang_totals": { + "in_today": in_today, + "feed_use_today": feed_use_today, + "out_today": out_today, + }, + "saldo_awal": saldo_awal, + "remote_cycle": remote_cycle, + } + return feed_sack, summary + + +def sync_karung_for_cycle( + cycle: Cycle, + *, + section: str = "today", +) -> tuple[FeedSacks, dict[str, Any]]: + """Sync today from sections, backfill cycle history from /api/combined, recompute totals.""" + feed_sack, summary = request_karung(cycle, section=section) + history_dates = backfill_karung_from_combined(cycle) + recompute_feed_sack_totals(cycle) + feed_sack.refresh_from_db() + summary = { + **summary, + "history_dates": [d.isoformat() for d in history_dates], + } + return feed_sack, summary diff --git a/backend/apps/operations/services/manual_input.py b/backend/apps/operations/services/manual_input.py new file mode 100644 index 0000000..c7b867d --- /dev/null +++ b/backend/apps/operations/services/manual_input.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from apps.farms.models import Cycle +from apps.operations.models import ManualInput + +DAILY_TO_TOTAL = ( + ("mortality_manual", "mortality_manual_total"), + ("feed_in_manual", "feed_in_manual_total"), + ("feed_use_manual", "feed_use_manual_total"), + ("feed_out_manual", "feed_out_manual_total"), + ("harvest_manual", "harvest_manual_total"), + ("harvest_weight_manual", "harvest_weight_manual_total"), +) + +SKIPPED_DERIVED_FIELDS = ( + "average_harvest_day_manual", + "average_harvest_weight_manual", + "fcr_manual", + "eef_manual", +) + + +def recompute_manual_totals(cycle: Cycle) -> None: + running = {total: 0 for _, total in DAILY_TO_TOTAL} + rows = list(ManualInput.objects.filter(cycle=cycle).order_by("date", "pk")) + for row in rows: + changed: list[str] = [] + for daily, total in DAILY_TO_TOTAL: + running[total] += getattr(row, daily) or 0 + if getattr(row, total) != running[total]: + setattr(row, total, running[total]) + changed.append(total) + for field in SKIPPED_DERIVED_FIELDS: + if getattr(row, field) != 0: + setattr(row, field, 0) + changed.append(field) + if changed: + row.save(update_fields=[*changed, "updated_at"]) diff --git a/backend/apps/operations/services/visibility.py b/backend/apps/operations/services/visibility.py new file mode 100644 index 0000000..abd59fa --- /dev/null +++ b/backend/apps/operations/services/visibility.py @@ -0,0 +1,29 @@ +"""Dashboard publish cutoff — day D data visible from 17:00 WIB on day D.""" + +from __future__ import annotations + +from datetime import date, datetime, time, timedelta + +from django.conf import settings +from django.utils import timezone + + +def dashboard_publish_time() -> time: + hour = int(getattr(settings, "DASHBOARD_PUBLISH_HOUR", 17)) + minute = int(getattr(settings, "DASHBOARD_PUBLISH_MINUTE", 0)) + return time(hour, minute) + + +def visible_through_date(now: datetime | None = None) -> date: + """Latest calendar date (WIB) allowed on dashboard reads.""" + if now is None: + now = timezone.localtime() + elif timezone.is_naive(now): + now = timezone.make_aware(now, timezone.get_current_timezone()) + else: + now = timezone.localtime(now) + + today = now.date() + if now.time() < dashboard_publish_time(): + return today - timedelta(days=1) + return today diff --git a/backend/apps/operations/tests.py b/backend/apps/operations/tests.py new file mode 100644 index 0000000..54566a8 --- /dev/null +++ b/backend/apps/operations/tests.py @@ -0,0 +1,441 @@ +from datetime import date, timedelta +from unittest.mock import patch + +from django.test import TestCase, override_settings +from rest_framework.test import APIClient + +from apps.accounts.models import User +from apps.farms.models import Cycle, Flock, Kandang, Site +from apps.operations.models import ChickenWeight, FeedSacks, IotPanel + + +@override_settings(DASHBOARD_PUBLISH_HOUR=0) +class OperationsAPITests(TestCase): + def setUp(self): + self.user = User.objects.create_user(user_name="tester", password="secret") + self.client = APIClient() + self.client.force_authenticate(self.user) + site = Site.objects.create(site_name="Sukawarna", user=self.user) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site) + self.cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=date.today() - timedelta(days=2), + end_date=date.today() + timedelta(days=32), + doc_in_weight=40, + doc_in_count=10000, + status=Cycle.STATUS_ACTIVE, + ) + self.flock = Flock.objects.create(flock_name="Flock A", kandang=self.kandang) + + def test_karungs_alias_lists_feed_sacks_with_date(self): + FeedSacks.objects.create( + cycle=self.cycle, + date=date.today(), + in_today=10, + out_today=8, + feed_use_today=8, + feed_use_total=8, + ) + response = self.client.get("/api/v1/karungs/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(results[0]["date"], date.today().isoformat()) + self.assertEqual(results[0]["feed_use_total"], 8) + self.assertEqual(results[0]["kandang"], self.kandang.pk) + self.assertEqual(results[0]["flock_id"], self.flock.pk) + + def test_karungs_latest_returns_newest_row(self): + FeedSacks.objects.create(cycle=self.cycle, date=date.today() - timedelta(days=1), out_today=1) + newest = FeedSacks.objects.create(cycle=self.cycle, date=date.today(), out_today=9) + response = self.client.get("/api/v1/karungs/latest/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["id"], newest.pk) + + def test_panel_iot_accepts_cycle_id(self): + IotPanel.objects.create( + flock=self.flock, + date=date.today(), + average_temperature=28.5, + ) + response = self.client.get("/api/v1/panel-iot/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["date"], date.today().isoformat()) + + def test_panel_iot_filters_by_flock(self): + flock_b = Flock.objects.create(flock_name="Flock B", kandang=self.kandang) + row = IotPanel.objects.create( + flock=self.flock, + date=date.today(), + average_temperature=28.5, + ) + IotPanel.objects.create( + flock=flock_b, + date=date.today(), + average_temperature=30.0, + ) + response = self.client.get( + "/api/v1/panel-iot/", + {"cycle_id": self.cycle.pk, "flock_id": self.flock.pk}, + ) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["id"], row.pk) + + def test_chicken_counting_uses_date_not_cameras(self): + response = self.client.post( + "/api/v1/chicken-countings/", + { + "cycle": self.cycle.pk, + "date": date.today().isoformat(), + "total_count": 9800, + "mortality_count": 12, + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + self.assertEqual(response.data["date"], date.today().isoformat()) + self.assertNotIn("counting_date", response.data) + self.assertNotIn("cam1_count", response.data) + + def test_weights_latest_avg_uses_date(self): + ChickenWeight.objects.create( + cycle=self.cycle, + date=date.today(), + age=10, + doc_weight=40, + average_weight=320.5, + chicken_count=9800, + uniformity=82.0, + average_daily_gain=28.0, + ) + response = self.client.get( + "/api/v1/chicken-weights/latest-avg/", {"cycle_id": self.cycle.pk} + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["date"], date.today().isoformat()) + self.assertEqual(response.data["average_weight"], 320.5) + self.assertNotIn("prediction_date", response.data) + + def test_weights_request_endpoint_is_removed(self): + response = self.client.post( + "/api/v1/chicken-weights/request/", + {"cycle_id": self.cycle.pk, "mode": "fetch"}, + format="json", + ) + self.assertEqual(response.status_code, 405) + + def test_health_does_not_probe_fatchicken(self): + response = self.client.get("/api/v1/health/") + self.assertEqual(response.status_code, 200) + self.assertNotIn("fatchicken", response.data) + self.assertNotIn("fatchicken_base_configured", response.data) + + def test_manual_input_uses_erd_field_names(self): + response = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": date.today().isoformat(), + "age_manual": 10, + "mortality_manual": 5, + "mortality_manual_total": 5, + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + self.assertEqual(response.data["mortality_manual_total"], 5) + self.assertNotIn("mortality_total_manual", response.data) + + def test_manual_input_computes_totals_and_ignores_client_derived_fields(self): + day1 = date.today() - timedelta(days=1) + day2 = date.today() + first = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": day1.isoformat(), + "age_manual": 9, + "mortality_manual": 5, + "feed_in_manual": 8, + "feed_use_manual": 10, + "harvest_manual": 2, + "harvest_weight_manual": 8, + "manual_weight": 320.5, + "mortality_manual_total": 999, + "feed_in_manual_total": 999, + "feed_use_manual_total": 999, + "harvest_manual_total": 999, + "harvest_weight_manual_total": 999, + "fcr_manual": 1.9, + "eef_manual": 400, + "average_harvest_day_manual": 12, + "average_harvest_weight_manual": 99, + }, + format="json", + ) + self.assertIn(first.status_code, (200, 201), first.data) + self.assertEqual(first.data["age_manual"], 9) + self.assertEqual(first.data["mortality_manual_total"], 5) + self.assertEqual(first.data["feed_in_manual_total"], 8) + self.assertEqual(first.data["feed_use_manual_total"], 10) + self.assertEqual(first.data["harvest_manual_total"], 2) + self.assertEqual(first.data["harvest_weight_manual_total"], 8) + self.assertEqual(first.data["fcr_manual"], 0) + self.assertEqual(first.data["eef_manual"], 0) + self.assertEqual(first.data["average_harvest_day_manual"], 0) + self.assertEqual(first.data["average_harvest_weight_manual"], 0) + + second = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": day2.isoformat(), + "age_manual": 10, + "mortality_manual": 3, + "feed_in_manual": 2, + "feed_use_manual": 4, + "harvest_manual": 1, + "harvest_weight_manual": 2, + "manual_weight": 330.0, + }, + format="json", + ) + self.assertIn(second.status_code, (200, 201), second.data) + self.assertEqual(second.data["mortality_manual_total"], 8) + self.assertEqual(second.data["feed_in_manual_total"], 10) + self.assertEqual(second.data["feed_use_manual_total"], 14) + self.assertEqual(second.data["harvest_manual_total"], 3) + self.assertEqual(second.data["harvest_weight_manual_total"], 10) + + update_day1 = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": day1.isoformat(), + "age_manual": 9, + "mortality_manual": 7, + "feed_in_manual": 8, + "feed_use_manual": 10, + "harvest_manual": 2, + "harvest_weight_manual": 8, + "manual_weight": 320.5, + }, + format="json", + ) + self.assertIn(update_day1.status_code, (200, 201), update_day1.data) + self.assertEqual(update_day1.data["id"], first.data["id"]) + self.assertEqual(update_day1.data["mortality_manual_total"], 7) + + refreshed_day2 = self.client.get( + "/api/v1/manual-inputs/", {"cycle_id": self.cycle.pk, "date": day2.isoformat()} + ) + self.assertEqual(refreshed_day2.status_code, 200, refreshed_day2.data) + rows = ( + refreshed_day2.data["results"] + if isinstance(refreshed_day2.data, dict) + else refreshed_day2.data + ) + self.assertEqual(rows[0]["mortality_manual_total"], 10) + + def test_manual_input_accepts_fractional_harvest_weight(self): + day1 = date.today() - timedelta(days=1) + day2 = date.today() + first = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": day1.isoformat(), + "harvest_weight_manual": 8.5, + }, + format="json", + ) + self.assertIn(first.status_code, (200, 201), first.data) + self.assertEqual(first.data["harvest_weight_manual"], 8.5) + self.assertEqual(first.data["harvest_weight_manual_total"], 8.5) + + second = self.client.post( + "/api/v1/manual-inputs/", + { + "cycle": self.cycle.pk, + "date": day2.isoformat(), + "harvest_weight_manual": 1.25, + }, + format="json", + ) + self.assertIn(second.status_code, (200, 201), second.data) + self.assertEqual(second.data["harvest_weight_manual"], 1.25) + self.assertEqual(second.data["harvest_weight_manual_total"], 9.75) + + def test_kpi_accepts_fractional_harvest_weight(self): + from apps.operations.models import ChickenCounting, FeedSacks, KPI, ManualInput + + cc = ChickenCounting.objects.create(cycle=self.cycle, date=date.today(), total_count=9800) + cw = ChickenWeight.objects.create( + cycle=self.cycle, + date=date.today(), + age=10, + doc_weight=40, + average_weight=320.5, + chicken_count=9800, + uniformity=82.0, + average_daily_gain=28.0, + ) + fs = FeedSacks.objects.create(cycle=self.cycle, date=date.today()) + manual = ManualInput.objects.create(cycle=self.cycle, date=date.today()) + response = self.client.post( + "/api/v1/kpis/", + { + "cycle": self.cycle.pk, + "date": date.today().isoformat(), + "cc": cc.pk, + "cw": cw.pk, + "fs": fs.pk, + "manual": manual.pk, + "harvest_weight": 12.75, + "harvest_weight_total": 20.5, + }, + format="json", + ) + self.assertEqual(response.status_code, 201, response.data) + self.assertEqual(response.data["harvest_weight"], 12.75) + self.assertEqual(response.data["harvest_weight_total"], 20.5) + kpi = KPI.objects.get(pk=response.data["id"]) + self.assertEqual(kpi.harvest_weight, 12.75) + self.assertEqual(kpi.harvest_weight_total, 20.5) + + +@override_settings(DASHBOARD_PUBLISH_HOUR=17, TIME_ZONE="Asia/Jakarta") +class DashboardVisibilityTests(TestCase): + def setUp(self): + self.user = User.objects.create_user(user_name="tester", password="secret") + self.client = APIClient() + self.client.force_authenticate(self.user) + site = Site.objects.create(site_name="Sukawarna", user=self.user) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site) + self.cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=35, + start_date=date(2026, 8, 26), + end_date=date(2026, 9, 29), + doc_in_weight=40, + doc_in_count=10000, + status=Cycle.STATUS_ACTIVE, + ) + + def test_hides_today_before_publish_time(self): + FeedSacks.objects.create( + cycle=self.cycle, + date=date(2026, 8, 27), + in_today=5, + out_today=3, + feed_use_today=3, + feed_use_total=3, + ) + FeedSacks.objects.create( + cycle=self.cycle, + date=date(2026, 8, 28), + in_today=9, + out_today=7, + feed_use_today=7, + feed_use_total=10, + ) + with patch( + "apps.operations.services.visibility.timezone.localtime", + ) as mock_localtime: + from datetime import datetime + from zoneinfo import ZoneInfo + + wib = ZoneInfo("Asia/Jakarta") + mock_localtime.return_value = datetime(2026, 8, 28, 16, 30, tzinfo=wib) + response = self.client.get("/api/v1/karungs/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["date"], "2026-08-27") + + def test_shows_today_after_publish_time(self): + FeedSacks.objects.create( + cycle=self.cycle, + date=date(2026, 8, 28), + in_today=9, + out_today=7, + feed_use_today=7, + feed_use_total=10, + ) + with patch( + "apps.operations.services.visibility.timezone.localtime", + ) as mock_localtime: + from datetime import datetime + from zoneinfo import ZoneInfo + + wib = ZoneInfo("Asia/Jakarta") + mock_localtime.return_value = datetime(2026, 8, 28, 17, 0, tzinfo=wib) + response = self.client.get("/api/v1/karungs/latest/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(response.data["date"], "2026-08-28") + + def test_panel_iot_not_hidden_before_publish_time(self): + flock = Flock.objects.create(flock_name="Flock A", kandang=self.kandang) + IotPanel.objects.create( + flock=flock, + date=date(2026, 8, 28), + average_temperature=28.5, + ) + with patch( + "apps.operations.services.visibility.timezone.localtime", + ) as mock_localtime: + from datetime import datetime + from zoneinfo import ZoneInfo + + wib = ZoneInfo("Asia/Jakarta") + mock_localtime.return_value = datetime(2026, 8, 28, 10, 0, tzinfo=wib) + response = self.client.get("/api/v1/panel-iot/", {"cycle_id": self.cycle.pk}) + self.assertEqual(response.status_code, 200, response.data) + results = response.data["results"] if isinstance(response.data, dict) else response.data + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["date"], "2026-08-28") + + def test_health_includes_visible_through_date(self): + with patch( + "apps.operations.services.visibility.timezone.localtime", + ) as mock_localtime: + from datetime import datetime + from zoneinfo import ZoneInfo + + wib = ZoneInfo("Asia/Jakarta") + mock_localtime.return_value = datetime(2026, 8, 28, 10, 0, tzinfo=wib) + response = self.client.get("/api/v1/health/") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data["visible_through_date"], "2026-08-27") + self.assertEqual(response.data["dashboard_publish_time"], "17:00") + + +class ErdPrimaryKeyTests(TestCase): + ERD_PRIMARY_KEYS = { + "user_access": "user_id", + "sites": "site_id", + "kandang": "kandang_id", + "flock": "flock_id", + "cycles": "cycle_id", + "iot_panel": "panel_id", + "ai_insight": "id", + "feed_sacks": "fs_id", + "chicken_counting": "cc_id", + "chicken_weight": "cw_id", + "manual_input": "manual_id", + "kpi": "kpi_id", + } + + def test_domain_primary_keys_match_erd_names(self): + from django.db import connection + + with connection.cursor() as cursor: + for table, pk_name in self.ERD_PRIMARY_KEYS.items(): + cursor.execute(f'PRAGMA table_info("{table}")') + live_pks = [row[1] for row in cursor.fetchall() if row[5]] + self.assertEqual(live_pks, [pk_name], table) + diff --git a/backend/apps/operations/tests_chicken_counting_edge.py b/backend/apps/operations/tests_chicken_counting_edge.py new file mode 100644 index 0000000..9e1fe27 --- /dev/null +++ b/backend/apps/operations/tests_chicken_counting_edge.py @@ -0,0 +1,213 @@ +from datetime import date +from unittest.mock import patch + +from django.test import TestCase, override_settings +from rest_framework.test import APIClient + +from apps.accounts.models import User +from apps.farms.models import Cycle, Kandang, Site +from apps.operations.models import ChickenCounting, ChickenWeight +from apps.operations.services.chicken_counting_edge import ( + ChickenCountingEdgeError, + aggregate_counting_by_date, + aggregate_mortality_by_date, + coop_for_kandang, + location_prefix_for_kandang, + sync_chicken_counting_for_cycle, +) + +DB_HISTORY_SAMPLE = [ + {"date": "2026-09-02", "location": "K1-L1", "total": 14591}, + {"date": "2026-09-02", "location": "K1-L2", "total": 14591}, + {"date": "2026-09-02", "location": "K2-L1", "total": 100}, + {"date": "2026-09-02", "location": "K2-L2", "total": 100}, + {"date": "2026-09-03", "location": "K1-L1", "total": 18736}, + {"date": "2026-09-03", "location": "K1-L2", "total": 18736}, + {"date": "2026-08-20", "location": "K1-L1", "total": 50}, +] + +MORTALITY_HISTORY_SAMPLE = [ + {"date": "2026-09-02", "coop": "K1", "total_mortality_count": 0}, + {"date": "2026-09-02", "coop": "K2", "total_mortality_count": 10}, + {"date": "2026-09-03", "coop": "K1", "total_mortality_count": 29}, + {"date": "2026-09-03", "coop": "K2", "total_mortality_count": 29}, +] + + +class LocationMappingTests(TestCase): + def test_maps_kandang_to_prefix_and_coop(self): + self.assertEqual(location_prefix_for_kandang("Kandang 1"), "K1") + self.assertEqual(coop_for_kandang("Kandang 2"), "K2") + + +class AggregationTests(TestCase): + def test_sums_matching_floors_per_date(self): + by_date = aggregate_counting_by_date(DB_HISTORY_SAMPLE, kandang_name="Kandang 1") + self.assertEqual(by_date[date(2026, 9, 2)], 29182) + self.assertEqual(by_date[date(2026, 9, 3)], 37472) + self.assertNotIn(date(2026, 9, 2), aggregate_counting_by_date([], kandang_name="Kandang 1")) + + def test_mortality_uses_matching_coop(self): + by_date = aggregate_mortality_by_date( + MORTALITY_HISTORY_SAMPLE, kandang_name="Kandang 1" + ) + self.assertEqual(by_date[date(2026, 9, 2)], 0) + self.assertEqual(by_date[date(2026, 9, 3)], 29) + + +@override_settings( + CHICKEN_COUNTING_EDGE_BASE_URL="http://edge.internal", + CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED=True, + CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED=True, +) +class SyncChickenCountingTests(TestCase): + def setUp(self): + user = User.objects.create_user(user_name="sync-user", password="secret") + site = Site.objects.create(site_name="Sukawarna", user=user) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site) + self.cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=33, + start_date=date(2026, 9, 2), + end_date=date(2026, 10, 4), + doc_in_weight=35, + doc_in_count=50000, + status=Cycle.STATUS_ACTIVE, + ) + + @patch("apps.operations.services.chicken_counting_edge.timezone.localdate") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_mortality_history") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_db_history") + def test_upserts_within_cycle_window(self, mock_db, mock_mort, mock_today): + mock_today.return_value = date(2026, 9, 4) + mock_db.return_value = DB_HISTORY_SAMPLE + mock_mort.return_value = MORTALITY_HISTORY_SAMPLE + + summary = sync_chicken_counting_for_cycle(self.cycle) + + self.assertEqual(sorted(summary["dates"]), [date(2026, 9, 2), date(2026, 9, 3)]) + row_sep2 = ChickenCounting.objects.get(cycle=self.cycle, date=date(2026, 9, 2)) + self.assertEqual(row_sep2.total_count, 29182) + self.assertEqual(row_sep2.mortality_count, 0) + row_sep3 = ChickenCounting.objects.get(cycle=self.cycle, date=date(2026, 9, 3)) + self.assertEqual(row_sep3.total_count, 37472) + self.assertEqual(row_sep3.mortality_count, 29) + self.assertFalse( + ChickenCounting.objects.filter(cycle=self.cycle, date=date(2026, 8, 20)).exists() + ) + + @patch("apps.operations.services.chicken_counting_edge.timezone.localdate") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_mortality_history") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_db_history") + def test_respects_partial_enable_flags(self, mock_db, mock_mort, mock_today): + mock_today.return_value = date(2026, 9, 4) + mock_db.return_value = DB_HISTORY_SAMPLE + mock_mort.return_value = MORTALITY_HISTORY_SAMPLE + ChickenCounting.objects.create( + cycle=self.cycle, + date=date(2026, 9, 2), + total_count=1, + mortality_count=5, + ) + + with override_settings( + CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED=False, + CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED=True, + ): + sync_chicken_counting_for_cycle(self.cycle) + + row = ChickenCounting.objects.get(cycle=self.cycle, date=date(2026, 9, 2)) + self.assertEqual(row.total_count, 1) + self.assertEqual(row.mortality_count, 0) + + +@override_settings( + CHICKEN_COUNTING_EDGE_BASE_URL="http://edge.internal", + CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED=True, + CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED=True, + DASHBOARD_PUBLISH_HOUR=17, + TIME_ZONE="Asia/Jakarta", +) +class ChickenCountingSyncApiTests(TestCase): + def setUp(self): + self.user = User.objects.create_user(user_name="tester", password="secret") + self.client = APIClient() + self.client.force_authenticate(self.user) + site = Site.objects.create(site_name="Sukawarna", user=self.user) + self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site) + self.cycle = Cycle.objects.create( + kandang=self.kandang, + total_days=33, + start_date=date(2026, 9, 2), + end_date=date(2026, 10, 4), + doc_in_weight=35, + doc_in_count=50000, + status=Cycle.STATUS_ACTIVE, + ) + + @patch("apps.operations.services.chicken_counting_edge.timezone.localdate") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_mortality_history") + @patch("apps.operations.services.chicken_counting_edge.ChickenCountingEdgeClient.fetch_db_history") + def test_sync_action_upserts(self, mock_db, mock_mort, mock_today): + mock_today.return_value = date(2026, 9, 4) + mock_db.return_value = DB_HISTORY_SAMPLE + mock_mort.return_value = MORTALITY_HISTORY_SAMPLE + + response = self.client.post( + "/api/v1/chicken-countings/sync/", + {"cycle_id": self.cycle.pk}, + format="json", + ) + self.assertEqual(response.status_code, 200, response.data) + self.assertEqual(ChickenCounting.objects.filter(cycle=self.cycle).count(), 2) + + @patch( + "apps.operations.views.sync_chicken_counting_for_cycle", + side_effect=ChickenCountingEdgeError("edge down"), + ) + def test_sync_action_returns_502_on_edge_error(self, _mock_sync): + response = self.client.post( + "/api/v1/chicken-countings/sync/", + {"cycle_id": self.cycle.pk}, + format="json", + ) + self.assertEqual(response.status_code, 502) + self.assertIn("edge down", response.data["detail"]) + + def test_counting_and_weight_visible_before_publish_time(self): + ChickenCounting.objects.create( + cycle=self.cycle, + date=date(2026, 9, 4), + total_count=100, + mortality_count=2, + ) + ChickenWeight.objects.create( + cycle=self.cycle, + date=date(2026, 9, 4), + age=2, + doc_weight=35, + average_weight=40, + chicken_count=10, + uniformity=90, + average_daily_gain=1, + ) + with patch("apps.operations.services.visibility.timezone.localtime") as mock_localtime: + from datetime import datetime + from zoneinfo import ZoneInfo + + wib = ZoneInfo("Asia/Jakarta") + mock_localtime.return_value = datetime(2026, 9, 4, 10, 0, tzinfo=wib) + counting = self.client.get( + "/api/v1/chicken-countings/", {"cycle_id": self.cycle.pk} + ) + weight = self.client.get( + "/api/v1/chicken-weights/", {"cycle_id": self.cycle.pk} + ) + self.assertEqual(counting.status_code, 200) + c_results = counting.data["results"] if isinstance(counting.data, dict) else counting.data + self.assertEqual(len(c_results), 1) + self.assertEqual(c_results[0]["date"], "2026-09-04") + self.assertEqual(weight.status_code, 200) + w_results = weight.data["results"] if isinstance(weight.data, dict) else weight.data + self.assertEqual(len(w_results), 1) + self.assertEqual(w_results[0]["date"], "2026-09-04") diff --git a/backend/apps/operations/tests_karung_web.py b/backend/apps/operations/tests_karung_web.py new file mode 100644 index 0000000..2044d44 --- /dev/null +++ b/backend/apps/operations/tests_karung_web.py @@ -0,0 +1,313 @@ +from datetime import date +from unittest.mock import patch + +from django.core.exceptions import ValidationError +from django.test import TestCase, override_settings + +from apps.accounts.models import User +from apps.farms.models import Cycle, Kandang, Site +from apps.operations.models import FeedSacks +from apps.operations.services.karung_web import ( + KarungWebError, + backfill_karung_from_combined, + daily_totals_from_combined_history, + fetch_iot_masuk_for_date, + initial_balance_accuracy, + masuk_source_for_kandang, + recompute_feed_sack_totals, + request_karung, + source_for_kandang, + sync_karung_for_cycle, +) + +ACTIVE_SECTIONS_SAMPLE = { + "sections": { + "today": { + "date": "2026-09-02", + "masuk": [ + {"karung": 192, "source": "K1 - In"}, + {"karung": 2, "source": "K1 - Out"}, + {"karung": 120, "source": "K2 - In"}, + {"karung": 5, "source": "K2 - Out"}, + ], + "tuang": [ + {"karung": 7, "source": "K1 - Use"}, + {"karung": 9, "source": "K2 - Use"}, + ], + "totals": {"masuk": 312, "tuang": 16}, + } + }, + "cycle": {"saldo_awal": 240}, +} + +COMBINED_SAMPLE = { + "masuk": { + "history": [ + {"counter_value": 160, "date": "2026-09-02", "id": 17, "source": "K1 - In"}, + {"counter_value": 80, "date": "2026-09-02", "id": 19, "source": "K2 - In"}, + {"counter_value": 112, "date": "2026-08-27", "id": 9, "source": "K1 - In"}, + {"counter_value": 32, "date": "2026-08-27", "id": 11, "source": "K2 - In"}, + ], + "today": [ + {"karung": 160, "source": "K1 - In"}, + {"karung": 80, "source": "K2 - In"}, + ], + } +} + +COMBINED_HISTORY_FULL = { + "masuk": { + "history": [ + {"counter_value": 192, "date": "2026-09-02", "source": "K1 - In"}, + {"counter_value": 1, "date": "2026-09-02", "source": "K1 - Out"}, + {"counter_value": 50, "date": "2026-09-03", "source": "K1 - In"}, + {"counter_value": 0, "date": "2026-09-03", "source": "K1 - Out"}, + {"counter_value": 120, "date": "2026-09-02", "source": "K2 - In"}, + {"counter_value": 2, "date": "2026-09-02", "source": "K2 - Out"}, + {"counter_value": 112, "date": "2026-08-27", "source": "K1 - In"}, + ], + "today": [], + }, + "tuang": { + "history": [ + {"counter_value": 7, "date": "2026-09-02", "source": "K1 - Use"}, + {"counter_value": 4, "date": "2026-09-03", "source": "K1 - Use"}, + {"counter_value": 9, "date": "2026-09-02", "source": "K2 - Use"}, + ], + "today": [], + }, +} + + +class MasukSourceForKandangTests(TestCase): + def test_maps_kandang_number_to_iot_source(self): + self.assertEqual(masuk_source_for_kandang("Kandang 1"), "K1 - In") + self.assertEqual(masuk_source_for_kandang("Kandang 2"), "K2 - In") + self.assertEqual(source_for_kandang("Kandang 2", kind="Use"), "K2 - Use") + self.assertEqual(source_for_kandang("Kandang 2", kind="Out"), "K2 - Out") + + def test_rejects_kandang_name_without_number(self): + with self.assertRaises(ValidationError): + masuk_source_for_kandang("Utara") + + +class InitialBalanceAccuracyTests(TestCase): + def test_returns_ratio_when_both_values_positive(self): + self.assertEqual(initial_balance_accuracy(120, 115), 95.8) + + def test_returns_100_when_both_zero(self): + self.assertEqual(initial_balance_accuracy(0, 0), 100.0) + + def test_returns_none_when_iot_missing(self): + self.assertIsNone(initial_balance_accuracy(120, None)) + + +@override_settings(KARUNG_WEB_ADMIN_BASE_URL="http://karung.internal") +class KarungWebCombinedTests(TestCase): + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_combined") + def test_fetch_iot_masuk_for_date_uses_kandang_specific_history_row(self, mock_fetch): + mock_fetch.return_value = COMBINED_SAMPLE + + result = fetch_iot_masuk_for_date(date(2026, 8, 27), kandang_name="Kandang 2") + + self.assertEqual(result, 32) + + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_combined") + def test_fetch_iot_masuk_for_date_matches_source_case_insensitively(self, mock_fetch): + mock_fetch.return_value = { + "masuk": { + "history": [ + {"counter_value": 99, "date": "2026-08-27", "source": "K1 - in"}, + ] + } + } + + result = fetch_iot_masuk_for_date(date(2026, 8, 27), kandang_name="Kandang 1") + + self.assertEqual(result, 99) + + @patch("apps.operations.services.karung_web.date") + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_combined") + def test_fetch_iot_masuk_for_date_falls_back_to_today_live_rows(self, mock_fetch, mock_date): + mock_date.today.return_value = date(2026, 9, 2) + mock_fetch.return_value = {"masuk": {"history": [], "today": COMBINED_SAMPLE["masuk"]["today"]}} + + result = fetch_iot_masuk_for_date(date(2026, 9, 2), kandang_name="Kandang 1") + + self.assertEqual(result, 160) + + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_combined") + def test_fetch_iot_masuk_for_date_returns_none_when_day_missing(self, mock_fetch): + mock_fetch.return_value = COMBINED_SAMPLE + + result = fetch_iot_masuk_for_date(date(2026, 8, 26), kandang_name="Kandang 1") + + self.assertIsNone(result) + + @patch( + "apps.operations.services.karung_web.KarungWebClient.fetch_combined", + side_effect=KarungWebError("upstream down"), + ) + def test_fetch_iot_masuk_for_date_propagates_upstream_errors(self, _mock_fetch): + with self.assertRaises(KarungWebError): + fetch_iot_masuk_for_date(date(2026, 8, 27), kandang_name="Kandang 1") + + +@override_settings(KARUNG_WEB_ADMIN_BASE_URL="http://karung.internal") +class RequestKarungTests(TestCase): + def setUp(self): + user = User.objects.create_user(user_name="tester", password="secret") + site = Site.objects.create(site_name="Sukawarna", user=user) + self.kandang1 = Kandang.objects.create(kandang_name="Kandang 1", site=site) + self.kandang2 = Kandang.objects.create(kandang_name="Kandang 2", site=site) + self.cycle1 = Cycle.objects.create( + kandang=self.kandang1, + total_days=35, + start_date=date(2026, 9, 2), + end_date=date(2026, 10, 5), + doc_in_weight=40, + doc_in_count=10000, + status=Cycle.STATUS_ACTIVE, + ) + self.cycle2 = Cycle.objects.create( + kandang=self.kandang2, + total_days=35, + start_date=date(2026, 9, 2), + end_date=date(2026, 10, 5), + doc_in_weight=40, + doc_in_count=10000, + status=Cycle.STATUS_ACTIVE, + ) + + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_active_sections") + def test_request_karung_uses_per_kandang_sources_not_aggregate_totals(self, mock_fetch): + mock_fetch.return_value = ACTIVE_SECTIONS_SAMPLE + + feed_sack1, summary1 = request_karung(self.cycle1, section="today") + feed_sack2, summary2 = request_karung(self.cycle2, section="today") + + self.assertEqual(feed_sack1.in_today, 192) + self.assertEqual(feed_sack1.feed_use_today, 7) + self.assertEqual(feed_sack1.out_today, 2) + self.assertEqual(feed_sack2.in_today, 120) + self.assertEqual(feed_sack2.feed_use_today, 9) + self.assertEqual(feed_sack2.out_today, 5) + self.assertEqual(summary1["kandang_totals"]["in_today"], 192) + self.assertEqual(summary2["kandang_totals"]["in_today"], 120) + + def test_daily_totals_from_combined_history_groups_by_date_for_kandang(self): + by_date = daily_totals_from_combined_history( + COMBINED_HISTORY_FULL, kandang_name="Kandang 1" + ) + + self.assertEqual( + by_date[date(2026, 9, 2)], + {"in_today": 192, "out_today": 1, "feed_use_today": 7}, + ) + self.assertEqual( + by_date[date(2026, 9, 3)], + {"in_today": 50, "out_today": 0, "feed_use_today": 4}, + ) + self.assertEqual( + by_date[date(2026, 8, 27)], + {"in_today": 112, "out_today": 0, "feed_use_today": 0}, + ) + self.assertNotIn(date(2026, 9, 1), by_date) + + @patch("apps.operations.services.karung_web.timezone") + def test_backfill_upserts_in_cycle_range_and_skips_outside(self, mock_tz): + mock_tz.localdate.return_value = date(2026, 9, 3) + + dates = backfill_karung_from_combined(self.cycle1, COMBINED_HISTORY_FULL) + + self.assertEqual(dates, [date(2026, 9, 2), date(2026, 9, 3)]) + row_sep2 = FeedSacks.objects.get(cycle=self.cycle1, date=date(2026, 9, 2)) + self.assertEqual(row_sep2.in_today, 192) + self.assertEqual(row_sep2.feed_use_today, 7) + self.assertEqual(row_sep2.out_today, 1) + self.assertFalse( + FeedSacks.objects.filter(cycle=self.cycle1, date=date(2026, 8, 27)).exists() + ) + + @patch("apps.operations.services.karung_web.timezone") + def test_backfill_refreshes_existing_row_from_upstream(self, mock_tz): + mock_tz.localdate.return_value = date(2026, 9, 3) + FeedSacks.objects.create( + cycle=self.cycle1, + date=date(2026, 9, 2), + in_today=1, + out_today=0, + feed_use_today=0, + in_total=1, + out_total=0, + feed_use_total=0, + ) + + backfill_karung_from_combined(self.cycle1, COMBINED_HISTORY_FULL) + + row = FeedSacks.objects.get(cycle=self.cycle1, date=date(2026, 9, 2)) + self.assertEqual(row.in_today, 192) + self.assertEqual(row.feed_use_today, 7) + self.assertEqual(row.out_today, 1) + + def test_recompute_feed_sack_totals_accumulates_in_date_order(self): + FeedSacks.objects.create( + cycle=self.cycle1, + date=date(2026, 9, 2), + in_today=192, + out_today=1, + feed_use_today=7, + in_total=0, + out_total=0, + feed_use_total=0, + ) + FeedSacks.objects.create( + cycle=self.cycle1, + date=date(2026, 9, 3), + in_today=50, + out_today=0, + feed_use_today=4, + in_total=0, + out_total=0, + feed_use_total=0, + ) + + recompute_feed_sack_totals(self.cycle1) + + sep2 = FeedSacks.objects.get(cycle=self.cycle1, date=date(2026, 9, 2)) + sep3 = FeedSacks.objects.get(cycle=self.cycle1, date=date(2026, 9, 3)) + self.assertEqual((sep2.in_total, sep2.feed_use_total, sep2.out_total), (192, 7, 1)) + self.assertEqual((sep3.in_total, sep3.feed_use_total, sep3.out_total), (242, 11, 1)) + + @patch("apps.operations.services.karung_web.timezone") + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_combined") + @patch("apps.operations.services.karung_web.KarungWebClient.fetch_active_sections") + def test_sync_karung_for_cycle_runs_today_then_history_backfill( + self, mock_sections, mock_combined, mock_tz + ): + mock_tz.localdate.return_value = date(2026, 9, 3) + mock_sections.return_value = { + "sections": { + "today": { + "date": "2026-09-03", + "masuk": [ + {"karung": 50, "source": "K1 - In"}, + {"karung": 0, "source": "K1 - Out"}, + ], + "tuang": [{"karung": 4, "source": "K1 - Use"}], + "totals": {"masuk": 50, "tuang": 4}, + } + }, + "cycle": {"saldo_awal": 0}, + } + mock_combined.return_value = COMBINED_HISTORY_FULL + + feed_sack, summary = sync_karung_for_cycle(self.cycle1, section="today") + + self.assertEqual(feed_sack.date, date(2026, 9, 3)) + self.assertEqual(feed_sack.in_today, 50) + self.assertEqual(feed_sack.in_total, 242) + sep2 = FeedSacks.objects.get(cycle=self.cycle1, date=date(2026, 9, 2)) + self.assertEqual(sep2.in_today, 192) + self.assertEqual(sep2.in_total, 192) + self.assertEqual(summary["history_dates"], ["2026-09-02", "2026-09-03"]) diff --git a/backend/apps/operations/urls.py b/backend/apps/operations/urls.py new file mode 100644 index 0000000..56a65cb --- /dev/null +++ b/backend/apps/operations/urls.py @@ -0,0 +1,29 @@ +from django.urls import path +from rest_framework.routers import DefaultRouter + +from apps.operations.views import ( + AIInsightViewSet, + ChickenCountingViewSet, + ChickenWeightViewSet, + FeedSacksViewSet, + HealthView, + IotPanelViewSet, + KPIViewSet, + ManualInputViewSet, +) + +router = DefaultRouter() +router.register("kpis", KPIViewSet, basename="kpi") +router.register("manual-inputs", ManualInputViewSet, basename="manual-input") +router.register("chicken-countings", ChickenCountingViewSet, basename="chicken-counting") +router.register("chicken-weights", ChickenWeightViewSet, basename="chicken-weight") +router.register("feed-sacks", FeedSacksViewSet, basename="feed-sacks") +router.register("karungs", FeedSacksViewSet, basename="karung") +router.register("iot-panels", IotPanelViewSet, basename="iot-panel") +router.register("panel-iot", IotPanelViewSet, basename="panel-iot") +router.register("ai-insights", AIInsightViewSet, basename="ai-insight") + +urlpatterns = [ + path("health/", HealthView.as_view(), name="health"), + *router.urls, +] diff --git a/backend/apps/operations/views.py b/backend/apps/operations/views.py new file mode 100644 index 0000000..2e4b9bc --- /dev/null +++ b/backend/apps/operations/views.py @@ -0,0 +1,256 @@ +from __future__ import annotations + +from django.conf import settings +from django.core.exceptions import ValidationError +from rest_framework import status, viewsets +from rest_framework.decorators import action +from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from rest_framework.views import APIView + +from apps.accounts.scoping import filter_cycles_queryset, filter_flocks_queryset +from apps.farms.models import Cycle, Flock +from apps.operations.models import ( + AIInsight, + ChickenCounting, + ChickenWeight, + FeedSacks, + IotPanel, + KPI, + ManualInput, +) +from apps.operations.serializers import ( + AIInsightSerializer, + ChickenCountingSerializer, + ChickenWeightSerializer, + FeedSacksSerializer, + IotPanelSerializer, + KPISerializer, + ManualInputSerializer, +) +from apps.operations.services.karung_web import KarungWebError, sync_karung_for_cycle +from apps.operations.services.chicken_counting_edge import ( + ChickenCountingEdgeError, + sync_chicken_counting_for_cycle, +) +from apps.operations.services.visibility import dashboard_publish_time, visible_through_date + +READ_ACTIONS = frozenset({"list", "retrieve", "latest_average", "latest", "dates"}) + + +class VisibilityFilteredMixin: + visibility_date_field = "date" + + def applies_visibility_filter(self) -> bool: + return getattr(self, "action", None) in READ_ACTIONS + + def filter_visible_through(self, qs): + if not self.applies_visibility_filter(): + return qs + cutoff = visible_through_date() + return qs.filter(**{f"{self.visibility_date_field}__lte": cutoff}) + + +class CycleScopedViewSet(VisibilityFilteredMixin, viewsets.ModelViewSet): + def get_queryset(self): + qs = super().get_queryset() + # Scope via cycle → kandang → site → owner + visible_cycles = filter_cycles_queryset(Cycle.objects.all(), self.request.user) + qs = qs.filter(cycle_id__in=visible_cycles.values_list("pk", flat=True)) + params = self.request.query_params + if params.get("cycle_id"): + qs = qs.filter(cycle_id=params["cycle_id"]) + if params.get("flock_id"): + qs = qs.filter(cycle__kandang__flocks=params["flock_id"]).distinct() + if params.get("date"): + qs = qs.filter(date=params["date"]) + return self.filter_visible_through(qs) + + +class KPIViewSet(CycleScopedViewSet): + queryset = KPI.objects.select_related("cycle").all() + serializer_class = KPISerializer + + +class ManualInputViewSet(CycleScopedViewSet): + queryset = ManualInput.objects.select_related("cycle").all() + serializer_class = ManualInputSerializer + + +class ChickenCountingViewSet(CycleScopedViewSet): + """Chicken counting + mortality IoT — not subject to dashboard publish cutoff.""" + + queryset = ChickenCounting.objects.select_related("cycle").all() + serializer_class = ChickenCountingSerializer + + def applies_visibility_filter(self) -> bool: + return False + + @action(detail=False, methods=["post"], url_path="sync") + def sync_from_edge(self, request): + cycle_id = request.data.get("cycle_id") + if not cycle_id: + return Response( + {"detail": "cycle_id is required."}, + status=status.HTTP_400_BAD_REQUEST, + ) + try: + cycle = filter_cycles_queryset( + Cycle.objects.select_related("kandang"), + request.user, + ).get(pk=cycle_id) + except Cycle.DoesNotExist: + return Response({"detail": "Cycle not found."}, status=status.HTTP_404_NOT_FOUND) + try: + summary = sync_chicken_counting_for_cycle(cycle) + except (ChickenCountingEdgeError, ValidationError) as exc: + code = getattr(exc, "status_code", None) + return Response( + {"detail": str(exc)}, + status=code if code and code >= 400 else status.HTTP_502_BAD_GATEWAY, + ) + return Response( + { + "upserted": summary["upserted"], + "dates": [d.isoformat() for d in summary["dates"]], + } + ) + + +class ChickenWeightViewSet(CycleScopedViewSet): + """Chicken weight — not subject to dashboard publish cutoff.""" + + queryset = ChickenWeight.objects.select_related("cycle").all() + serializer_class = ChickenWeightSerializer + + def applies_visibility_filter(self) -> bool: + return False + + @action(detail=False, methods=["get"], url_path="latest-avg") + def latest_average(self, request): + cycle_id = request.query_params.get("cycle_id") + if not cycle_id: + return Response( + {"detail": "cycle_id is required."}, + status=status.HTTP_400_BAD_REQUEST, + ) + row = self.get_queryset().filter(cycle_id=cycle_id).order_by("-date", "-pk").first() + if row is None: + return Response( + {"detail": "No chicken weight exists for this cycle."}, + status=status.HTTP_404_NOT_FOUND, + ) + return Response(self.get_serializer(row).data) + + +class FeedSacksViewSet(CycleScopedViewSet): + queryset = FeedSacks.objects.select_related("cycle").all() + serializer_class = FeedSacksSerializer + + @action(detail=False, methods=["get"], url_path="latest") + def latest(self, request): + cycle_id = request.query_params.get("cycle_id") + if not cycle_id: + return Response( + {"detail": "cycle_id is required."}, + status=status.HTTP_400_BAD_REQUEST, + ) + row = self.get_queryset().filter(cycle_id=cycle_id).order_by("-date", "-pk").first() + if row is None: + return Response( + {"detail": "No feed sacks row exists for this cycle."}, + status=status.HTTP_404_NOT_FOUND, + ) + return Response(self.get_serializer(row).data) + + @action(detail=False, methods=["post"], url_path="request") + def request_sync(self, request): + cycle_id = request.data.get("cycle_id") + if not cycle_id: + return Response( + {"detail": "cycle_id is required."}, + status=status.HTTP_400_BAD_REQUEST, + ) + try: + cycle = filter_cycles_queryset(Cycle.objects.all(), request.user).get(pk=cycle_id) + except Cycle.DoesNotExist: + return Response({"detail": "Cycle not found."}, status=status.HTTP_404_NOT_FOUND) + section = request.data.get("section") or "today" + try: + feed_sack, summary = sync_karung_for_cycle(cycle, section=section) + except (KarungWebError, ValidationError) as exc: + code = getattr(exc, "status_code", None) + return Response( + {"detail": str(exc)}, + status=code if code and code >= 400 else status.HTTP_502_BAD_GATEWAY, + ) + return Response( + {"karung": self.get_serializer(feed_sack).data, "upstream": summary} + ) + + +class IotPanelViewSet(viewsets.ModelViewSet): + """IoT panel is real-time — not subject to the 17:00 dashboard publish cutoff.""" + queryset = IotPanel.objects.select_related("flock", "flock__kandang").all() + serializer_class = IotPanelSerializer + + def get_queryset(self): + qs = super().get_queryset() + visible_flocks = filter_flocks_queryset(Flock.objects.all(), self.request.user) + qs = qs.filter(flock_id__in=visible_flocks.values_list("pk", flat=True)) + params = self.request.query_params + cycle_id = params.get("cycle_id") + if cycle_id: + visible_cycles = filter_cycles_queryset(Cycle.objects.all(), self.request.user) + try: + cycle = visible_cycles.get(pk=cycle_id) + except Cycle.DoesNotExist: + return qs.none() + qs = qs.filter( + flock__kandang_id=cycle.kandang_id, + date__gte=cycle.start_date, + date__lte=cycle.end_date, + ) + if params.get("flock_id"): + qs = qs.filter(flock_id=params["flock_id"]) + if params.get("date"): + qs = qs.filter(date=params["date"]) + return qs + + def paginate_queryset(self, queryset): + if self.request.query_params.get("date"): + return None + return super().paginate_queryset(queryset) + + @action(detail=False, methods=["get"], url_path="dates") + def dates(self, request): + dates = list( + self.get_queryset() + .order_by("date") + .values_list("date", flat=True) + .distinct() + ) + return Response(dates) + + +class AIInsightViewSet(CycleScopedViewSet): + queryset = AIInsight.objects.select_related("cycle").all() + serializer_class = AIInsightSerializer + + +class HealthView(APIView): + permission_classes = [AllowAny] + authentication_classes = [] + + def get(self, request): + cutoff = visible_through_date() + publish = dashboard_publish_time() + payload = { + "status": "ok", + "service": "newdashboard-api", + "karung_web_admin_base_configured": bool(settings.KARUNG_WEB_ADMIN_BASE_URL), + "visible_through_date": cutoff.isoformat(), + "dashboard_publish_time": publish.strftime("%H:%M"), + "dashboard_timezone": settings.TIME_ZONE, + } + return Response(payload) diff --git a/backend/apps/sync/__init__.py b/backend/apps/sync/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/sync/apps.py b/backend/apps/sync/apps.py new file mode 100644 index 0000000..3d00640 --- /dev/null +++ b/backend/apps/sync/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class SyncConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.sync" + label = "sync" + verbose_name = "City sync registry" diff --git a/backend/apps/sync/management/__init__.py b/backend/apps/sync/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/sync/management/commands/__init__.py b/backend/apps/sync/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/sync/migrations/0001_initial.py b/backend/apps/sync/migrations/0001_initial.py new file mode 100644 index 0000000..370e791 --- /dev/null +++ b/backend/apps/sync/migrations/0001_initial.py @@ -0,0 +1,52 @@ +# Generated manually for HQ city registry scaffold + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="CitySite", + fields=[ + ("city_site_id", models.BigAutoField(primary_key=True, serialize=False)), + ( + "code", + models.SlugField( + help_text="Stable id, e.g. sukawarna", + max_length=64, + unique=True, + ), + ), + ("name", models.CharField(max_length=120)), + ( + "api_base_url", + models.URLField( + help_text="City API root including /api/v1, e.g. https://site.example/api/v1", + max_length=255, + ), + ), + ( + "api_key", + models.CharField( + blank=True, + help_text="X-API-Key for pulling from the city API (keep server-side only)", + max_length=255, + ), + ), + ("is_active", models.BooleanField(default=True)), + ("last_synced_at", models.DateTimeField(blank=True, null=True)), + ("last_sync_status", models.CharField(blank=True, default="", max_length=32)), + ("last_sync_message", models.TextField(blank=True, default="")), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ], + options={ + "db_table": "city_sites", + "ordering": ["name"], + }, + ), + ] diff --git a/backend/apps/sync/migrations/0002_citysite_registered_by.py b/backend/apps/sync/migrations/0002_citysite_registered_by.py new file mode 100644 index 0000000..601e321 --- /dev/null +++ b/backend/apps/sync/migrations/0002_citysite_registered_by.py @@ -0,0 +1,27 @@ +# Generated for city site ownership + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("sync", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="citysite", + name="registered_by", + field=models.ForeignKey( + blank=True, + help_text="GM / GM Admin who added this city dashboard URL", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="registered_city_sites", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/backend/apps/sync/migrations/__init__.py b/backend/apps/sync/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/sync/models.py b/backend/apps/sync/models.py new file mode 100644 index 0000000..28398fd --- /dev/null +++ b/backend/apps/sync/models.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from django.conf import settings +from django.db import models + + +class CitySite(models.Model): + """ + Registry of a city dashboard-cpsp deployment that HQ can mirror from. + + Outbound API key is stored here for local/dev scaffolding. Prefer a secret + manager or encrypted field before production. + """ + + city_site_id = models.BigAutoField(primary_key=True) + code = models.SlugField(max_length=64, unique=True, help_text="Stable id, e.g. sukawarna") + name = models.CharField(max_length=120) + api_base_url = models.URLField( + max_length=255, + help_text="City API root including /api/v1, e.g. https://site.example/api/v1", + ) + api_key = models.CharField( + max_length=255, + blank=True, + help_text="X-API-Key for pulling from the city API (keep server-side only)", + ) + registered_by = models.ForeignKey( + settings.AUTH_USER_MODEL, + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="registered_city_sites", + help_text="GM / GM Admin who added this city dashboard URL", + ) + is_active = models.BooleanField(default=True) + last_synced_at = models.DateTimeField(null=True, blank=True) + last_sync_status = models.CharField(max_length=32, blank=True, default="") + last_sync_message = models.TextField(blank=True, default="") + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + db_table = "city_sites" + ordering = ["name"] + + def __str__(self) -> str: + return f"{self.name} ({self.code})" diff --git a/backend/apps/sync/serializers.py b/backend/apps/sync/serializers.py new file mode 100644 index 0000000..dbd597e --- /dev/null +++ b/backend/apps/sync/serializers.py @@ -0,0 +1,60 @@ +from rest_framework import serializers + +from apps.sync.models import CitySite + + +class CitySiteSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="pk", read_only=True) + # Never echo the outbound city API key back to the browser by default. + has_api_key = serializers.SerializerMethodField() + registered_by_name = serializers.CharField( + source="registered_by.user_name", read_only=True, allow_null=True + ) + + class Meta: + model = CitySite + fields = [ + "id", + "code", + "name", + "api_base_url", + "has_api_key", + "registered_by", + "registered_by_name", + "is_active", + "last_synced_at", + "last_sync_status", + "last_sync_message", + "created_at", + "updated_at", + ] + read_only_fields = [ + "id", + "has_api_key", + "registered_by", + "registered_by_name", + "last_synced_at", + "last_sync_status", + "last_sync_message", + "created_at", + "updated_at", + ] + + def get_has_api_key(self, obj: CitySite) -> bool: + return bool(obj.api_key) + + +class CitySiteWriteSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="pk", read_only=True) + + class Meta: + model = CitySite + fields = [ + "id", + "code", + "name", + "api_base_url", + "api_key", + "is_active", + ] + extra_kwargs = {"api_key": {"write_only": True, "required": False}} diff --git a/backend/apps/sync/urls.py b/backend/apps/sync/urls.py new file mode 100644 index 0000000..dd8bf5a --- /dev/null +++ b/backend/apps/sync/urls.py @@ -0,0 +1,11 @@ +from django.urls import include, path +from rest_framework.routers import DefaultRouter + +from apps.sync.views import CitySiteViewSet + +router = DefaultRouter() +router.register("city-sites", CitySiteViewSet, basename="city-site") + +urlpatterns = [ + path("", include(router.urls)), +] diff --git a/backend/apps/sync/views.py b/backend/apps/sync/views.py new file mode 100644 index 0000000..71b61ed --- /dev/null +++ b/backend/apps/sync/views.py @@ -0,0 +1,77 @@ +from rest_framework import status, viewsets +from rest_framework.decorators import action +from rest_framework.response import Response + +from apps.accounts.permissions import CanRegisterCitySite, IsExecutive, can_sync +from apps.accounts.scoping import filter_city_sites_queryset +from apps.farms.services.city_registry import ensure_hq_site_for_city +from apps.sync.models import CitySite +from apps.sync.serializers import CitySiteSerializer, CitySiteWriteSerializer + + +class CitySiteViewSet(viewsets.ModelViewSet): + """ + List/read: scoped (director all; BUH managed GMs; GM own). + Create/update/delete: GM and GM Admin. + Sync: GM and GM Admin only (stubs until mirror pull is implemented). + + Creating a city site also attaches (or creates) an HQ Site so farm data + appears in the executive view list. + """ + + executive_sync_action = True + + def get_queryset(self): + qs = CitySite.objects.select_related("registered_by").all() + return filter_city_sites_queryset(qs, self.request.user) + + def get_permissions(self): + if self.action in {"create", "update", "partial_update", "destroy"}: + return [CanRegisterCitySite()] + return [IsExecutive()] + + def get_serializer_class(self): + if self.action in {"create", "update", "partial_update"}: + return CitySiteWriteSerializer + return CitySiteSerializer + + def perform_create(self, serializer): + city = serializer.save(registered_by=self.request.user) + ensure_hq_site_for_city(city) + + def perform_update(self, serializer): + city = serializer.save() + if city.is_active: + ensure_hq_site_for_city(city) + + @action(detail=True, methods=["post"], url_path="sync") + def sync(self, request, pk=None): + if not can_sync(request.user): + return Response({"detail": "Sync not allowed."}, status=status.HTTP_403_FORBIDDEN) + city = self.get_object() + if not city.is_active: + return Response( + {"detail": "City site is inactive."}, + status=status.HTTP_400_BAD_REQUEST, + ) + return Response( + { + "detail": "City sync not implemented yet.", + "city_site": CitySiteSerializer(city).data, + }, + status=status.HTTP_501_NOT_IMPLEMENTED, + ) + + @action(detail=False, methods=["post"], url_path="sync-all") + def sync_all(self, request): + if not can_sync(request.user): + return Response({"detail": "Sync not allowed."}, status=status.HTTP_403_FORBIDDEN) + cities = list(self.get_queryset().filter(is_active=True)) + return Response( + { + "detail": "City sync-all not implemented yet.", + "city_count": len(cities), + "cities": CitySiteSerializer(cities, many=True).data, + }, + status=status.HTTP_501_NOT_IMPLEMENTED, + ) diff --git a/backend/config/__init__.py b/backend/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/config/asgi.py b/backend/config/asgi.py new file mode 100644 index 0000000..856079b --- /dev/null +++ b/backend/config/asgi.py @@ -0,0 +1,7 @@ +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") + +application = get_asgi_application() diff --git a/backend/config/gunicorn.py b/backend/config/gunicorn.py new file mode 100644 index 0000000..2957113 --- /dev/null +++ b/backend/config/gunicorn.py @@ -0,0 +1,6 @@ +bind = "0.0.0.0:8000" +workers = 2 +threads = 2 +timeout = 120 +accesslog = "-" +errorlog = "-" diff --git a/backend/config/settings.py b/backend/config/settings.py new file mode 100644 index 0000000..626b99e --- /dev/null +++ b/backend/config/settings.py @@ -0,0 +1,211 @@ +"""Django settings for New Dashboard (ERD-aligned DRF API).""" + +from __future__ import annotations + +import json +import os +from pathlib import Path + +from dotenv import load_dotenv + +BASE_DIR = Path(__file__).resolve().parent.parent +load_dotenv(BASE_DIR / ".env") + + +def env(key: str, default: str | None = None) -> str | None: + return os.getenv(key, default) + + +def env_bool(key: str, default: bool = False) -> bool: + value = os.getenv(key) + if value is None: + return default + return value.strip().lower() in {"1", "true", "yes", "on"} + + +def env_list(key: str, default: str = "") -> list[str]: + raw = os.getenv(key, default) + return [item.strip() for item in raw.split(",") if item.strip()] + + +def env_json_dict(key: str, default: str = "") -> dict[str, int]: + raw = os.getenv(key, default) + if not raw: + return {} + data = json.loads(raw) + return {str(k): int(v) for k, v in data.items()} + + +SECRET_KEY = env("SECRET_KEY", "insecure-dev-key") +DEBUG = env_bool("DEBUG", True) +ALLOWED_HOSTS = env_list("ALLOWED_HOSTS", "localhost,127.0.0.1,dashboard.local") +CSRF_TRUSTED_ORIGINS = env_list( + "CSRF_TRUSTED_ORIGINS", + "http://localhost:3002,http://127.0.0.1:3002,http://localhost,http://127.0.0.1", +) +if DEBUG: + # Dev/LAN: allow Vite (:3001) and Docker UI (:80) from private networks. + CSRF_TRUSTED_ORIGIN_REGEXES = [ + r"^http://localhost:\d+$", + r"^http://127\.0\.0\.1:\d+$", + r"^http://192\.168\.\d{1,3}\.\d{1,3}:\d+$", + r"^http://10\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$", + ] + +INSTALLED_APPS = [ + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "rest_framework", + "corsheaders", + "drf_spectacular", + "apps.accounts", + "apps.farms", + "apps.operations", + "apps.jobs", + "apps.sync", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "corsheaders.middleware.CorsMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "config.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [BASE_DIR / "templates"], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "config.wsgi.application" + +DB_ENGINE = env("DB_ENGINE", "django.db.backends.sqlite3") +if DB_ENGINE == "django.db.backends.sqlite3": + DATABASES = { + "default": { + "ENGINE": DB_ENGINE, + "NAME": env("DB_NAME", str(BASE_DIR / "db.sqlite3")), + } + } +else: + DATABASES = { + "default": { + "ENGINE": DB_ENGINE, + "NAME": env("DB_NAME", "newdashboard"), + "USER": env("DB_USER", "newdashboard"), + "PASSWORD": env("DB_PASSWORD", ""), + "HOST": env("DB_HOST", "localhost"), + "PORT": env("DB_PORT", "5432"), + } + } + +AUTH_USER_MODEL = "accounts.User" + +AUTH_PASSWORD_VALIDATORS = [ + {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, +] + +LANGUAGE_CODE = "en-us" +TIME_ZONE = "Asia/Jakarta" +USE_I18N = True +USE_TZ = True + +STATIC_URL = "/static/" +STATIC_ROOT = BASE_DIR / "staticfiles" +MEDIA_URL = "/media/" +MEDIA_ROOT = BASE_DIR / "media" + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +CORS_ALLOWED_ORIGINS = env_list( + "CORS_ALLOWED_ORIGINS", + "http://localhost:3002,http://127.0.0.1:3002,http://localhost,http://127.0.0.1", +) +CORS_ALLOW_CREDENTIALS = env_bool("CORS_ALLOW_CREDENTIALS", True) + +SESSION_COOKIE_SECURE = env_bool("SESSION_COOKIE_SECURE", False) +CSRF_COOKIE_SECURE = env_bool("CSRF_COOKIE_SECURE", False) +SESSION_COOKIE_HTTPONLY = True +CSRF_COOKIE_HTTPONLY = False + +REST_FRAMEWORK = { + "DEFAULT_AUTHENTICATION_CLASSES": [ + "apps.accounts.authentication.ApiKeyAuthentication", + "rest_framework.authentication.SessionAuthentication", + ], + "DEFAULT_PERMISSION_CLASSES": [ + "rest_framework.permissions.IsAuthenticated", + ], + "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", + "PAGE_SIZE": int(env("API_PAGE_SIZE", "50") or "50"), + "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", +} + +SPECTACULAR_SETTINGS = { + "TITLE": "CPSP Executive HQ API", + "DESCRIPTION": "Main-office mirror API for executive dashboard (session + API key auth).", + "VERSION": "0.1.0", +} + +BOOTSTRAP_API_KEY = env("BOOTSTRAP_API_KEY", "") or "" + +BOOTSTRAP_ADMIN_USER = env("BOOTSTRAP_ADMIN_USER", "admin") or "admin" +BOOTSTRAP_ADMIN_PASSWORD = env("BOOTSTRAP_ADMIN_PASSWORD", "") or "" +BOOTSTRAP_STAFF_USER = env("BOOTSTRAP_STAFF_USER", "") or "" +BOOTSTRAP_STAFF_PASSWORD = env("BOOTSTRAP_STAFF_PASSWORD", "") or "" + +KARUNG_WEB_ADMIN_BASE_URL = ( + env("KARUNG_WEB_ADMIN_BASE_URL", "http://127.0.0.1:5000") or "" +).rstrip("/") +KARUNG_WEB_ADMIN_TIMEOUT_SECONDS = float( + env("KARUNG_WEB_ADMIN_TIMEOUT_SECONDS", "30") or "30" +) +# City-edge syncs are OFF by default at HQ — data should arrive via city-site mirror sync. +KARUNG_WEB_ADMIN_SYNC_ENABLED = env_bool("KARUNG_WEB_ADMIN_SYNC_ENABLED", False) + +# Dashboard publish cutoff (WIB): day D visible from this time on day D. +DASHBOARD_PUBLISH_HOUR = int(env("DASHBOARD_PUBLISH_HOUR", "17") or "17") +DASHBOARD_PUBLISH_MINUTE = int(env("DASHBOARD_PUBLISH_MINUTE", "0") or "0") + +# External IoT flocks API — unused at HQ by default (mirror from cities instead). +IOT_API_BASE_URL = (env("IOT_API_BASE_URL", "https://dashboard.cpsp.id/api/iot/flocks") or "").rstrip("/") +IOT_API_SYNC_TIMEOUT_SECONDS = float(env("IOT_API_SYNC_TIMEOUT_SECONDS", "60") or "60") +IOT_SYNC_ENABLED = env_bool("IOT_SYNC_ENABLED", False) +IOT_SYNC_LOOKBACK_MINUTES = int(env("IOT_SYNC_LOOKBACK_MINUTES", "20") or "20") +IOT_SYNC_MAX_PAGES = int(env("IOT_SYNC_MAX_PAGES", "10") or "10") +IOT_FLOCK_ID_MAP = env_json_dict("IOT_FLOCK_ID_MAP") + +CHICKEN_COUNTING_EDGE_BASE_URL = ( + env("CHICKEN_COUNTING_EDGE_BASE_URL", "") or "" +).rstrip("/") +CHICKEN_COUNTING_EDGE_TIMEOUT_SECONDS = float( + env("CHICKEN_COUNTING_EDGE_TIMEOUT_SECONDS", "30") or "30" +) +CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED = env_bool( + "CHICKEN_COUNTING_EDGE_COUNTING_SYNC_ENABLED", False +) +CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED = env_bool( + "CHICKEN_COUNTING_EDGE_MORTALITY_SYNC_ENABLED", False +) diff --git a/backend/config/urls.py b/backend/config/urls.py new file mode 100644 index 0000000..5611608 --- /dev/null +++ b/backend/config/urls.py @@ -0,0 +1,20 @@ +from django.conf import settings +from django.conf.urls.static import static +from django.urls import include, path +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView + +urlpatterns = [ + path("api/schema/", SpectacularAPIView.as_view(), name="schema"), + path( + "api/docs/", + SpectacularSwaggerView.as_view(url_name="schema"), + name="swagger-ui", + ), + path("api/v1/", include("apps.accounts.urls")), + path("api/v1/", include("apps.farms.urls")), + path("api/v1/", include("apps.operations.urls")), + path("api/v1/", include("apps.sync.urls")), +] + +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/backend/config/wsgi.py b/backend/config/wsgi.py new file mode 100644 index 0000000..8509335 --- /dev/null +++ b/backend/config/wsgi.py @@ -0,0 +1,7 @@ +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") + +application = get_wsgi_application() diff --git a/backend/database/ERD_Dashboard_Chicken_Counting.md b/backend/database/ERD_Dashboard_Chicken_Counting.md new file mode 100644 index 0000000..c10b351 --- /dev/null +++ b/backend/database/ERD_Dashboard_Chicken_Counting.md @@ -0,0 +1,325 @@ +# Entity Relationship Diagram (ERD) & Unified Master Architecture + +This document defines the integrated **Audrix Smart Poultry Platform ERD (`ERD_audrix`)** and how the **Chicken Counting & Weight Estimation Vision System** connects directly into the master farm database. + +--- + +## 🗺️ Unified Master Mermaid ERD (`ERD_audrix` Integration) + +```mermaid +erDiagram + %% ========================================== + %% 1. CORE ENTERPRISE HIERARCHY (ERD_audrix) + %% ========================================== + USER_ACCESS ||--|{ SITES : "manages" + SITES ||--|{ KANDANG : "contains" + KANDANG ||--|{ CYCLES : "runs" + CYCLES ||--|{ FLOCK : "houses" + + %% ========================================== + %% 2. OUR DOMAIN: EDGE TOPOLOGY & VISION + %% ========================================== + KANDANG ||--|{ FLOOR : "has_levels" + FLOOR ||--|{ CAMERA : "equipped_with" + FLOOR ||--o{ BATCH_RUNS : "executes" + CAMERA ||--o{ BATCH_RUNS : "records" + BATCH_RUNS ||--o{ DETECTIONS : "captures_tracks" + + %% ========================================== + %% 3. VISION ROLLUPS -> MASTER AUDRIX TABLES + %% ========================================== + CYCLES ||--o{ CHICKEN_COUNTING : "records_daily_count" + CYCLES ||--o{ CHICKEN_WEIGHT : "records_daily_weight" + BATCH_RUNS ||--o{ CHICKEN_COUNTING : "aggregates_into_cc" + BATCH_RUNS ||--o{ CHICKEN_WEIGHT : "aggregates_into_cw" + + %% ========================================== + %% 4. NON-VISION EXTERNAL STREAMS (DO NOT TOUCH) + %% ========================================== + FLOCK ||--o{ IOT_PANEL : "monitored_by" + CYCLES ||--o{ FEED_SACKS : "tracks_inventory" + CYCLES ||--o{ MANUAL_INPUT : "logs_ground_truth" + CYCLES ||--o{ AI_INSIGHT : "generates_alerts" + + %% ========================================== + %% 5. MASTER KPI AGGREGATION (ERD_audrix) + %% ========================================== + CYCLES ||--o{ KPI : "computes_daily_kpi" + CHICKEN_COUNTING ||--o{ KPI : "feeds_headcount" + CHICKEN_WEIGHT ||--o{ KPI : "feeds_vision_weight" + FEED_SACKS ||--o{ KPI : "feeds_feed_usage" + MANUAL_INPUT ||--o{ KPI : "feeds_manual_weights" + + %% ========================================== + %% ENTITY DEFINITIONS + %% ========================================== + + USER_ACCESS { + int user_id PK "NOT NULL" + varchar user_name "30 NOT NULL" + varchar password_hash "255 NOT NULL" + varchar status "30 NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + SITES { + int site_id PK "NOT NULL" + varchar site_name "30 NOT NULL" + int user_id FK "References USER_ACCESS" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + KANDANG { + int kandang_id PK "NOT NULL" + varchar kandang_name "30 NOT NULL" + int site_id FK "References SITES" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + CYCLES { + int cycle_id PK "NOT NULL (Flock Batch Run)" + int kandang_id FK "References KANDANG" + int total_days "NOT NULL" + date start_date "NOT NULL (Day 0)" + date end_date "NOT NULL" + int doc_in_weight "NOT NULL (Initial DOC weight for this cycle)" + int doc_in_count "NOT NULL (Stocking inventory)" + varchar status "30 NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + FLOCK { + int flock_id PK "NOT NULL" + varchar flock_name "30 NOT NULL" + int cycle_id FK "References CYCLES" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + FLOOR { + string floor_id PK "e.g. K1-L1, K1-L2" + int kandang_id FK "References KANDANG" + string level "Floor level designation (L1, L2, L3)" + json roi_points "Counting gate coordinates" + float px_per_cm "Spatial calibration constant" + } + + CAMERA { + string camera_id PK "e.g. CC1, CC2, CC3, CC4" + string floor_id FK "References FLOOR" + int camera_num "1 to 4" + float px_per_cm "Camera pixel to cm calibration" + string stream_url "Source video / RTSP stream" + } + + BATCH_RUNS { + integer id PK "AUTOINCREMENT (SQLite edge runs)" + string date "YYYY-MM-DD" + string location FK "References FLOOR(floor_id)" + string camera_id FK "References CAMERA(camera_id)" + integer total_entered "Headcount count validated" + integer frames_processed + real elapsed_seconds + string stopped_reason + string source_video + string generated_at + integer cycle_day "0 = DOC count only, 1+ = Weight active" + real area_cm2_median "Median body area (cm^2)" + real minor_axis_cm_median "Median width (cm)" + real major_axis_cm_median "Median length (cm)" + real predicted_weight_g "Estimated weight (g)" + real gompertz_baseline_g "Expected curve weight (g)" + real vision_gain_g "Vision allometric gain (g)" + integer n_weight_samples "Valid sample count" + real rejection_rate "MAD outlier filter rejection rate" + } + + DETECTIONS { + string date "YYYY-MM-DD" + string camera_id FK + integer track_id "BoT-SORT track identifier" + integer class_id "0 = chicken" + float confidence "YOLO confidence score" + integer frame_index "Count trigger frame" + float bbox_area_cm2 "Area in cm^2" + float width_cm "Width in cm" + float height_cm "Height in cm" + float minor_axis_cm "min(width, height) cm" + float major_axis_cm "max(width, height) cm" + float aspect_ratio_cm "width / height" + float perimeter_cm "Perimeter cm" + float mad_zscore "MAD Z-score outlier metric" + } + + CHICKEN_COUNTING { + int cc_id PK "NOT NULL" + int cycle_id FK "References CYCLES" + date date "NOT NULL" + int total_count "NOT NULL (Aggregated total from edge BATCH_RUNS)" + int mortality_count "NOT NULL (Carcasses from vision segmentation)" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + CHICKEN_WEIGHT { + int cw_id PK "NOT NULL" + int cycle_id FK "References CYCLES" + date date "NOT NULL" + int age "NOT NULL (Cycle Day: 1+)" + int doc_weight "NOT NULL (Cycle-specific initial DOC weight)" + float average_weight "NOT NULL (predicted_weight_g from edge)" + int chicken_count "NOT NULL (n_weight_samples)" + float uniformity "NOT NULL (Flock weight uniformity %)" + float average_daily_gain "NOT NULL (ADG in grams/day)" + float area_cm2_median "Median body area in cm^2" + float minor_axis_cm_median "Median minor axis / width in cm" + float major_axis_cm_median "Median major axis / length in cm" + float gompertz_baseline_g "Theoretical Gompertz curve baseline" + float vision_gain_g "Allometric vision gain residual" + float rejection_rate "MAD outlier filter rejection percentage" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + } + + IOT_PANEL { + int panel_id PK "NOT NULL" + date date "NOT NULL" + float wind_speed "NOT NULL" + float humidity "NOT NULL" + float water_total "NOT NULL" + float average_temperature "NOT NULL" + float experience_temperature "NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + int flock_id FK "References FLOCK" + } + + FEED_SACKS { + int fs_id PK "NOT NULL (fc_id)" + date date "NOT NULL" + int in_today "NOT NULL" + int out_today "NOT NULL" + int in_total "NOT NULL" + int out_total "NOT NULL" + int feed_use_today "NOT NULL" + int feed_use_total "NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + int cycle_id FK "References CYCLES" + } + + MANUAL_INPUT { + int manual_id PK "NOT NULL" + date date "NOT NULL" + int age_manual "NOT NULL" + int mortality_manual "NOT NULL" + int mortality_manual_total "NOT NULL" + int feed_in_manual "NOT NULL" + int feed_use_manual "NOT NULL" + int feed_in_manual_total "NOT NULL" + int feed_use_manual_total "NOT NULL" + int harverst_manual "NOT NULL" + int harverst_manual_total "NOT NULL" + float harvest_weight_manual "NOT NULL" + float harvest_weight_manual_total "NOT NULL" + float manual_weight "NOT NULL" + float average_harvest_day_manual "NOT NULL" + float average_harvest_weight_manual "NOT NULL" + float fcr_manual "NOT NULL" + float eef_manual "NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + int cycle_id FK "References CYCLES" + } + + AI_INSIGHT { + int id PK "NOT NULL" + date date "NOT NULL" + text insight_text "NOT NULL" + string alert "NOT NULL" + varchar section "100 NOT NULL" + varchar session "100 NOT NULL" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + int cycle_id FK "References CYCLES" + } + + KPI { + int kpi_id PK "NOT NULL" + date date "NOT NULL" + int age "NOT NULL" + int mortality "NOT NULL" + int mortality_total "NOT NULL" + int feed "NOT NULL" + int feed_total "NOT NULL" + int harverst "NOT NULL" + int harverst_total "NOT NULL" + float harvest_weight "NOT NULL" + float harvest_weight_total "NOT NULL" + int chicken_life "NOT NULL" + float chicken_life_percentage "NOT NULL" + float iot_weight "NOT NULL" + float average_harvest_day "NOT NULL" + float average_harvest_weight "NOT NULL" + float fcr "NOT NULL (Feed Conversion Ratio)" + float eef "NOT NULL (European Efficiency Factor)" + timestamp created_at "NOT NULL" + timestamp updated_at "NOT NULL" + int cycle_id FK "References CYCLES" + int cc_id FK "References CHICKEN_COUNTING" + int cw_id FK "References CHICKEN_WEIGHT" + int fs_id FK "References FEED_SACKS" + int manual_id FK "References MANUAL_INPUT" + } +``` + +--- + +## 🏗️ Architectural Tier Descriptions & Integration Mapping + +### Tier 1: Farm Hierarchy (`USER_ACCESS` $\to$ `SITES` $\to$ `KANDANG` $\to$ `CYCLES` $\to$ `FLOCK`) + +- Belongs to master `ERD_audrix`. +- Defines farm ownership, coops, operational commercial cycles (`CYCLES`), and biological flocks (`FLOCK`). + +--- + +### Tier 2: Edge Vision Subsystem (`FLOOR` $\to$ `CAMERA` $\to$ `BATCH_RUNS` $\to$ `DETECTIONS`) + +- **Physical Hierarchy:** Each `KANDANG` has multiple floor levels (`FLOOR`), and each floor operates 4 top-down optical counting cameras (`CAMERA`: CC1, CC2, CC3, CC4) calibrated by `px_per_cm`. +- **Execution & Curation:** Daily batch runs process video feeds on the edge and populate SQLite table `BATCH_RUNS` and Parquet observation datasets (`DETECTIONS`). +- **Cycle Day 0 Rule:** Day 0 is strictly for initial stocking headcount (`total_entered`), while Day 1+ calculates both headcount and vision-derived geometric body weights. + +--- + +### Tier 3: Vision Aggregations to Audrix Tables (`CHICKEN_COUNTING` & `CHICKEN_WEIGHT`) + +Our edge pipeline aggregates floor camera runs and pushes clean daily rollups directly into the two vision tables of `ERD_audrix`: + +1. **`CHICKEN_COUNTING` (`cc_id`)**: + - `total_count` $\leftarrow \sum \text{total\_entered}$ across all floor cameras for that date. + - `mortality_count` $\leftarrow \text{total dead carcasses detected by mortality segmentation}$. +2. **`CHICKEN_WEIGHT` (`cw_id`)**: + - `average_weight` $\leftarrow \text{fused predicted weight in grams}$. + - `chicken_count` $\leftarrow \sum \text{n\_weight\_samples}$ (valid non-outlier tracks). + - `uniformity` $\leftarrow \text{flock size uniformity percentage}$. + - `average_daily_gain` $\leftarrow \text{daily weight gain in grams/day}$. + - `area_cm2_median`, `minor_axis_cm_median`, `major_axis_cm_median` $\leftarrow \text{calibrated physical dimensions}$. + - `gompertz_baseline_g`, `vision_gain_g` $\leftarrow \text{audited growth model residual breakdown}$. + +--- + +### Tier 4: Master Analytics & KPI Synthesis (`KPI`) + +- `KPI` is the central analytics ledger that combines: + - Vision counts from `CHICKEN_COUNTING` (`cc_id`). + - Vision body weights from `CHICKEN_WEIGHT` (`cw_id`). + - Daily feed intake from `FEED_SACKS` (`fs_id`). + - Human ground truth logs from `MANUAL_INPUT` (`manual_id`). +- Computes macro biological & economic efficiency indicators: + $$\text{FCR} = \frac{\text{Total Feed Consumed (kg)}}{\text{Total Harvest / Live Weight (kg)}}$$ + $$\text{EEF} = \frac{\text{Livability \%} \times \text{Average Weight (kg)}}{\text{Age (Days)} \times \text{FCR}} \times 100$$ diff --git a/backend/database/ERD_dashboard.png b/backend/database/ERD_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..8add559791e260194937a8f818dcd2d41a61858c GIT binary patch literal 306998 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 z%0DovKaJchRciiM+q?V0i*qSo7Y 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

HNcyb}*l>F}7_#eUzwy%=b>L7Q? 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 Xf~UIlzOq92%DSUU8j8vC2Dknf5qVY) literal 0 HcmV?d00001 diff --git a/backend/database/erd_schema.sql b/backend/database/erd_schema.sql new file mode 100644 index 0000000..3bd7c4a --- /dev/null +++ b/backend/database/erd_schema.sql @@ -0,0 +1,315 @@ +-- ============================================================================= +-- PostgreSQL Schema — CPSP Dashboard ERD +-- Source: ERD_dashboard.png (updated 2026-08-20) +-- +-- user_access.status: active | inactive | superadmin +-- (Django syncs is_active/is_staff/is_superuser from status on save: +-- inactive => all false; superadmin => is_active/is_superuser true, +-- is_staff false; active => is_active true, is_superuser false, is_staff +-- left untouched so operators can be marked staff) +-- user_access → sites → kandang → cycles +-- cycles → flock (flock.cycle_id, required; cycles has no flock_id) +-- flock → iot_panel +-- cycles → ai_insight, feed_sacks, chicken_counting, chicken_weight, +-- manual_input, kpi +-- kpi → chicken_counting, chicken_weight, feed_sacks, manual_input +-- ============================================================================= + +-- ----------------------------------------------------------------------------- +-- 1. User Access +-- Django AbstractBaseUser + PermissionsMixin. `status` is the app's role +-- (active | inactive | superadmin); Django auth flags are synced from it on +-- save (is_staff stays untouched for active users, superadmin => is_staff +-- false, is_superuser true). +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS user_access ( + user_id SERIAL PRIMARY KEY, + user_name VARCHAR(30) NOT NULL UNIQUE, + password VARCHAR(128) NOT NULL, + last_login TIMESTAMP WITH TIME ZONE, + is_superuser BOOLEAN NOT NULL DEFAULT FALSE, + is_staff BOOLEAN NOT NULL DEFAULT FALSE, + is_active BOOLEAN NOT NULL DEFAULT TRUE, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(30) NOT NULL +); + +CREATE INDEX IF NOT EXISTS idx_user_access_status ON user_access (status); + +-- Django PermissionsMixin many-to-many tables. +CREATE TABLE IF NOT EXISTS user_access_groups ( + id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES user_access (user_id) ON DELETE CASCADE, + group_id INTEGER NOT NULL REFERENCES auth_group (id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS user_access_user_permissions ( + id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES user_access (user_id) ON DELETE CASCADE, + permission_id INTEGER NOT NULL REFERENCES auth_permission (id) ON DELETE CASCADE +); + +-- ----------------------------------------------------------------------------- +-- 2. Sites +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS sites ( + site_id SERIAL PRIMARY KEY, + site_name VARCHAR(30) NOT NULL, + user_id INTEGER NOT NULL REFERENCES user_access (user_id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX IF NOT EXISTS idx_sites_user_id ON sites (user_id); + +-- ----------------------------------------------------------------------------- +-- 3. Kandang (Coop / Pen) +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS kandang ( + kandang_id SERIAL PRIMARY KEY, + kandang_name VARCHAR(30) NOT NULL, + site_id INTEGER NOT NULL REFERENCES sites (site_id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX IF NOT EXISTS idx_kandang_site_id ON kandang (site_id); + +-- ----------------------------------------------------------------------------- +-- 4. Cycles +-- No flock_id — flock belongs to cycle via flock.cycle_id. +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS cycles ( + cycle_id SERIAL PRIMARY KEY, + total_days INTEGER NOT NULL, + start_date DATE NOT NULL, + end_date DATE NOT NULL, + doc_in_weight INTEGER NOT NULL, + doc_in_count INTEGER NOT NULL, + feed_initial_balance INTEGER NOT NULL DEFAULT 0, + feed_initial_balance_date DATE, + status VARCHAR(30) NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + kandang_id INTEGER NOT NULL REFERENCES kandang (kandang_id) ON DELETE CASCADE, + CONSTRAINT chk_cycles_date_range CHECK (end_date >= start_date) +); + +CREATE INDEX IF NOT EXISTS idx_cycles_kandang_id ON cycles (kandang_id); +CREATE INDEX IF NOT EXISTS idx_cycles_status ON cycles (status); +CREATE INDEX IF NOT EXISTS idx_cycles_start_date ON cycles (start_date); + +-- ----------------------------------------------------------------------------- +-- 5. Flock +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS flock ( + flock_id SERIAL PRIMARY KEY, + flock_name VARCHAR(30) NOT NULL, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX IF NOT EXISTS idx_flock_cycle_id ON flock (cycle_id); + +-- ----------------------------------------------------------------------------- +-- 6. IoT Panel +-- One row per sensor reading; the panel polls every 10 minutes, so a cycle +-- day holds up to 144 rows. `timestamp` carries the reading time; `date` is +-- kept denormalized for fast daily grouping. +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS iot_panel ( + panel_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + timestamp TIMESTAMP WITH TIME ZONE, + wind_speed FLOAT NOT NULL, + humidity FLOAT NOT NULL, + water_total FLOAT NOT NULL, + average_temperature FLOAT NOT NULL, + experience_temperature FLOAT NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + flock_id INTEGER NOT NULL REFERENCES flock (flock_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_iot_panel_flock_id ON iot_panel (flock_id); +CREATE INDEX IF NOT EXISTS idx_iot_panel_date ON iot_panel (date); +CREATE INDEX IF NOT EXISTS idx_iot_panel_timestamp ON iot_panel (timestamp); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_iot_panel_flock_timestamp ON iot_panel (flock_id, timestamp); + +-- ----------------------------------------------------------------------------- +-- 7. AI Insight +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS ai_insight ( + id SERIAL PRIMARY KEY, + date DATE NOT NULL, + insight_text TEXT NOT NULL, + alert VARCHAR(100) NOT NULL, + section VARCHAR(100) NOT NULL, + session VARCHAR(100) NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_ai_insight_cycle_id ON ai_insight (cycle_id); +CREATE INDEX IF NOT EXISTS idx_ai_insight_date ON ai_insight (date); + +-- ----------------------------------------------------------------------------- +-- 8. Feed Sacks +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS feed_sacks ( + fs_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + in_today INTEGER NOT NULL DEFAULT 0, + out_today INTEGER NOT NULL DEFAULT 0, + in_total INTEGER NOT NULL DEFAULT 0, + out_total INTEGER NOT NULL DEFAULT 0, + feed_use_today INTEGER NOT NULL DEFAULT 0, + feed_use_total INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_feed_sacks_cycle_id ON feed_sacks (cycle_id); +CREATE INDEX IF NOT EXISTS idx_feed_sacks_date ON feed_sacks (date); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_feed_sacks_cycle_date ON feed_sacks (cycle_id, date); + +-- ----------------------------------------------------------------------------- +-- 9. Chicken Counting +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS chicken_counting ( + cc_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + total_count INTEGER NOT NULL DEFAULT 0, + mortality_count INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_chicken_counting_cycle_id ON chicken_counting (cycle_id); +CREATE INDEX IF NOT EXISTS idx_chicken_counting_date ON chicken_counting (date); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_chicken_counting_cycle_date ON chicken_counting (cycle_id, date); + +-- ----------------------------------------------------------------------------- +-- 10. Chicken Weight +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS chicken_weight ( + cw_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + age INTEGER NOT NULL, + doc_weight INTEGER NOT NULL, + average_weight FLOAT NOT NULL, + chicken_count INTEGER NOT NULL, + uniformity FLOAT NOT NULL, + average_daily_gain FLOAT NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_chicken_weight_cycle_id ON chicken_weight (cycle_id); +CREATE INDEX IF NOT EXISTS idx_chicken_weight_date ON chicken_weight (date); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_chicken_weight_cycle_date ON chicken_weight (cycle_id, date); + +-- ----------------------------------------------------------------------------- +-- 11. Manual Input +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS manual_input ( + manual_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + age_manual INTEGER NOT NULL DEFAULT 0, + mortality_manual INTEGER NOT NULL DEFAULT 0, + mortality_manual_total INTEGER NOT NULL DEFAULT 0, + feed_in_manual INTEGER NOT NULL DEFAULT 0, + feed_use_manual INTEGER NOT NULL DEFAULT 0, + feed_in_manual_total INTEGER NOT NULL DEFAULT 0, + feed_use_manual_total INTEGER NOT NULL DEFAULT 0, + feed_out_manual INTEGER NOT NULL DEFAULT 0, + feed_out_manual_total INTEGER NOT NULL DEFAULT 0, + harvest_manual INTEGER NOT NULL DEFAULT 0, + harvest_manual_total INTEGER NOT NULL DEFAULT 0, + harvest_weight_manual FLOAT NOT NULL DEFAULT 0, + harvest_weight_manual_total FLOAT NOT NULL DEFAULT 0, + manual_weight FLOAT NOT NULL DEFAULT 0, + average_harvest_day_manual FLOAT NOT NULL DEFAULT 0, + average_harvest_weight_manual FLOAT NOT NULL DEFAULT 0, + fcr_manual FLOAT NOT NULL DEFAULT 0, + eef_manual FLOAT NOT NULL DEFAULT 0, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_manual_input_cycle_id ON manual_input (cycle_id); +CREATE INDEX IF NOT EXISTS idx_manual_input_date ON manual_input (date); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_manual_input_cycle_date ON manual_input (cycle_id, date); + +-- ----------------------------------------------------------------------------- +-- 12. KPI (aggregates data from cycle + source records) +-- ----------------------------------------------------------------------------- +CREATE TABLE IF NOT EXISTS kpi ( + kpi_id SERIAL PRIMARY KEY, + date DATE NOT NULL, + age INTEGER NOT NULL DEFAULT 0, + mortality INTEGER NOT NULL DEFAULT 0, + mortality_total INTEGER NOT NULL DEFAULT 0, + feed INTEGER NOT NULL DEFAULT 0, + feed_total INTEGER NOT NULL DEFAULT 0, + harvest INTEGER NOT NULL DEFAULT 0, + harvest_total INTEGER NOT NULL DEFAULT 0, + harvest_weight FLOAT NOT NULL DEFAULT 0, + harvest_weight_total FLOAT NOT NULL DEFAULT 0, + chicken_life INTEGER NOT NULL DEFAULT 0, + chicken_life_percentage FLOAT NOT NULL DEFAULT 0, + iot_weight FLOAT NOT NULL DEFAULT 0, + average_harvest_day FLOAT NOT NULL DEFAULT 0, + average_harvest_weight FLOAT NOT NULL DEFAULT 0, + fcr FLOAT NOT NULL DEFAULT 0, + eef FLOAT NOT NULL DEFAULT 0, + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + cycle_id INTEGER NOT NULL REFERENCES cycles (cycle_id) ON DELETE CASCADE, + cc_id INTEGER NOT NULL REFERENCES chicken_counting (cc_id) ON DELETE RESTRICT, + cw_id INTEGER NOT NULL REFERENCES chicken_weight (cw_id) ON DELETE RESTRICT, + fs_id INTEGER NOT NULL REFERENCES feed_sacks (fs_id) ON DELETE RESTRICT, + manual_id INTEGER NOT NULL REFERENCES manual_input (manual_id) ON DELETE RESTRICT +); + +CREATE INDEX IF NOT EXISTS idx_kpi_cycle_id ON kpi (cycle_id); +CREATE INDEX IF NOT EXISTS idx_kpi_date ON kpi (date); +CREATE UNIQUE INDEX IF NOT EXISTS uniq_kpi_cycle_date ON kpi (cycle_id, date); + +-- ============================================================================= +-- Auto-update updated_at on row changes +-- ============================================================================= +CREATE OR REPLACE FUNCTION erd_set_updated_at() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = CURRENT_TIMESTAMP; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +DO $$ +DECLARE + tbl TEXT; +BEGIN + FOREACH tbl IN ARRAY ARRAY[ + 'user_access', 'sites', 'kandang', 'cycles', 'flock', + 'iot_panel', 'ai_insight', 'feed_sacks', 'chicken_counting', + 'chicken_weight', 'manual_input', 'kpi' + ] + LOOP + EXECUTE format('DROP TRIGGER IF EXISTS trg_%I_updated_at ON %I', tbl, tbl); + EXECUTE format( + 'CREATE TRIGGER trg_%I_updated_at BEFORE UPDATE ON %I + FOR EACH ROW EXECUTE FUNCTION erd_set_updated_at()', + tbl, tbl + ); + END LOOP; +END; +$$; diff --git a/backend/dev.mjs b/backend/dev.mjs new file mode 100644 index 0000000..ec62d59 --- /dev/null +++ b/backend/dev.mjs @@ -0,0 +1,56 @@ +/** + * Run Django management commands from this backend folder. + * Usage: + * node dev.mjs # runserver 0.0.0.0:8001 + * node dev.mjs migrate + * node dev.mjs seed_demo + */ +import { spawn } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const djangoRoot = path.dirname(fileURLToPath(import.meta.url)); + +if (!existsSync(path.join(djangoRoot, 'manage.py'))) { + console.error('[backend] manage.py not found.'); + process.exit(1); +} + +const extra = process.argv.slice(2); +const manageArgs = + extra.length === 0 + ? ['manage.py', 'runserver', '0.0.0.0:8001'] + : ['manage.py', ...extra]; + +function resolvePython() { + const isWin = process.platform === 'win32'; + const venvPython = isWin + ? path.join(djangoRoot, '.venv', 'Scripts', 'python.exe') + : path.join(djangoRoot, '.venv', 'bin', 'python'); + + if (existsSync(venvPython)) { + return venvPython; + } + + return isWin ? 'python' : 'python3'; +} + +const python = resolvePython(); +const child = spawn(python, manageArgs, { + cwd: djangoRoot, + stdio: 'inherit', + env: process.env, +}); + +child.on('error', (err) => { + console.error(`[backend] Failed to start ${python}:`, err.message); + process.exit(1); +}); + +child.on('exit', (code, signal) => { + if (signal) { + process.exit(1); + } + process.exit(code ?? 0); +}); diff --git a/backend/manage.py b/backend/manage.py new file mode 100644 index 0000000..f1b0e57 --- /dev/null +++ b/backend/manage.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Is it installed and available on your PYTHONPATH?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..9fd5338 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,13 @@ +{ + "name": "dashboard-cpsp-executive-backend", + "private": true, + "version": "0.1.0", + "type": "module", + "description": "HQ mirror API for dashboard-cpsp-executive", + "scripts": { + "dev": "node dev.mjs", + "migrate": "node dev.mjs migrate", + "seed": "node dev.mjs seed_demo", + "start": "node dev.mjs" + } +} diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..6754975 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,9 @@ +Django>=5.1,<5.3 +djangorestframework>=3.15,<4.0 +drf-spectacular>=0.27,<1.0 +django-cors-headers>=4.4,<5.0 +python-dotenv>=1.0,<2.0 +gunicorn>=23.0,<24.0 +psycopg[binary]>=3.2,<4.0 +httpx>=0.27,<1.0 +openpyxl>=3.1,<4.0 diff --git a/components/AccountAdminShell.tsx b/components/AccountAdminShell.tsx new file mode 100644 index 0000000..c5c20e7 --- /dev/null +++ b/components/AccountAdminShell.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { useAuth } from '../context/AuthContext.tsx'; +import UserManagementPage from './UserManagementPage.tsx'; + +const AccountAdminShell: React.FC = () => { + const { user, logout } = useAuth(); + const roleLabel = user?.is_superuser ? 'Superuser' : 'Account Admin'; + + return ( +

+ +
+
+ +
+
+
+ ); +}; + +export default AccountAdminShell; diff --git a/components/CobbStandardPage.tsx b/components/CobbStandardPage.tsx new file mode 100644 index 0000000..b27a665 --- /dev/null +++ b/components/CobbStandardPage.tsx @@ -0,0 +1,181 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { cobbStandardPerformance } from '../mockData/cobbStandard.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { formatNumber, formatRatio } from '../utils/format.ts'; + +const CobbStandardPage: React.FC = () => { + const { selectedCycle } = useFarm(); + const [initialBw, setInitialBw] = useState(selectedCycle?.chick_in_weight || 42); + const [capacity, setCapacity] = useState(selectedCycle?.doc_in_count || 50000); + + useEffect(() => { + if (selectedCycle?.chick_in_weight) setInitialBw(selectedCycle.chick_in_weight); + if (selectedCycle?.doc_in_count) setCapacity(selectedCycle.doc_in_count); + }, [selectedCycle?.chick_in_weight, selectedCycle?.doc_in_count]); + + const calculatedData = useMemo(() => { + const results = []; + let lastBw = Number(initialBw); + let lastCumFeed = 0; + for (const standard of cobbStandardPerformance) { + const currentBw = lastBw * (1 + standard.dailyGainPercent); + const dailyGainG = currentBw - lastBw; + const cumFeedG = currentBw * standard.fcr; + const dailyFeedG = cumFeedG - lastCumFeed; + const feedKg = (dailyFeedG * capacity) / 1000; + const feedBag = feedKg / 50; + results.push({ + day: standard.day, + bw: Math.round(currentBw), + dailyGainG: Math.round(dailyGainG), + dailyGainPercent: standard.dailyGainPercent, + dailyFeedG: Math.round(dailyFeedG), + cumFeedG: Math.round(cumFeedG), + fcr: standard.fcr, + feedKg: Math.round(feedKg), + feedBag: Math.round(feedBag), + }); + lastBw = currentBw; + lastCumFeed = cumFeedG; + } + return results; + }, [initialBw, capacity]); + + return ( +
+
+ +
+

Kalkulator Standar Performa

+

+ Hitung proyeksi pertumbuhan dan kebutuhan pakan berdasarkan bobot awal dan kapasitas + kandang. +

+
+
+
+
+ + setInitialBw(Number(e.target.value))} + className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-red-500 focus:border-red-500 text-lg font-semibold" + /> +
+
+ + setCapacity(Number(e.target.value))} + className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-red-500 focus:border-red-500 text-lg font-semibold" + /> +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + {calculatedData.map((row) => { + const isSeventhDay = row.day > 0 && row.day % 7 === 0; + const rowClass = `hover:bg-red-50 ${isSeventhDay ? 'font-bold bg-blue-100' : 'even:bg-gray-100/50'}`; + const cellBorderClass = isSeventhDay + ? 'border-b-[3px] border-double border-blue-400' + : 'border-gray-200'; + return ( + + + + + + + + + + + + ); + })} + +
+ Umur + + BW (g) + + Daily Gain + + Feed Consumption + + FCR + + Kebutuhan Pakan +
(g)(%)Daily (g)Cum (g)(Kg)(Bag)
+ 0 + + {initialBw} +
+ {row.day} + + {formatNumber(row.bw)} + + {formatNumber(row.dailyGainG)} + + {(row.dailyGainPercent * 100).toFixed(0)}% + + {formatNumber(row.dailyFeedG)} + + {formatNumber(row.cumFeedG)} + + {formatRatio(row.fcr)} + + {formatNumber(row.feedKg)} + + {formatNumber(row.feedBag)} +
+
+
+
+ Standar Performa COBB (2018) +
+
+ ); +}; + +export default CobbStandardPage; diff --git a/components/CycleTimeline.tsx b/components/CycleTimeline.tsx new file mode 100644 index 0000000..b19aa31 --- /dev/null +++ b/components/CycleTimeline.tsx @@ -0,0 +1,172 @@ +import React, { useEffect, useState } from 'react'; +import { useFarm } from '../context/FarmContext.tsx'; +import { formatDateId, formatDateRange, resolveCycleStatus } from '../utils/format.ts'; +import type { Cycle } from '../types/api.ts'; + +type Phase = { name: string; startDay: number; endDay: number; color: string }; + +function phasesFor(totalDays: number): Phase[] { + const starterEnd = Math.min(10, totalDays); + const growerEnd = Math.min(24, totalDays); + const phases: Phase[] = [ + { name: 'Starter', startDay: 1, endDay: starterEnd, color: 'bg-red-400' }, + ]; + if (growerEnd > starterEnd) { + phases.push({ + name: 'Grower', + startDay: starterEnd + 1, + endDay: growerEnd, + color: 'bg-orange-400', + }); + } + if (totalDays > growerEnd) { + phases.push({ + name: 'Finisher', + startDay: growerEnd + 1, + endDay: totalDays, + color: 'bg-yellow-500', + }); + } + return phases; +} + +const statusConfig = { + active: { label: 'Active', bg: 'bg-red-100', text: 'text-red-800', icon: 'fa-running' }, + closed: { + label: 'Completed', + bg: 'bg-green-100', + text: 'text-green-800', + icon: 'fa-check-circle', + }, +}; + +const SingleCycleView: React.FC<{ cycle: Cycle }> = ({ cycle }) => { + const phases = phasesFor(cycle.total_days); + const currentDay = Math.min(Math.max(cycle.current_day, 0), cycle.total_days); + const cycleStatus = resolveCycleStatus(cycle); + const progress = cycle.total_days > 0 ? (currentDay / cycle.total_days) * 100 : 0; + + return ( +
+
+

+ Siklus:{' '} + {formatDateRange(cycle.start_date, cycle.end_date)} +

+
+

Estimasi Panen

+

{formatDateId(cycle.end_date)}

+
+
+
+
+ {phases.map((phase) => { + const width = ((phase.endDay - phase.startDay + 1) / cycle.total_days) * 100; + return ( +
+ {phase.name} +
+ ); + })} +
+ {cycleStatus === 'active' && ( +
+
+
+ Hari ke-{currentDay} +
+
+
+
+ )} +
+
+ Hari 1 + + {formatDateId(cycle.start_date)} + + + Berat DOC: {cycle.chick_in_weight} gram + + + DOC In: {cycle.doc_in_count.toLocaleString('id-ID')} ekor + +
+
+ Hari {cycle.total_days} + + {formatDateId(cycle.end_date)} + +
+
+
+
+ ); +}; + +const CycleTimeline: React.FC = () => { + const { cycles, selectedCycleId, setSelectedCycleId } = useFarm(); + const [localId, setLocalId] = useState(selectedCycleId); + + useEffect(() => { + setLocalId(selectedCycleId); + }, [selectedCycleId]); + + const selected = cycles.find((c) => c.id === localId) ?? null; + + return ( +
+

Linimasa Siklus Produksi

+ {cycles.length === 0 ? ( +

+ Belum ada siklus untuk kandang ini. Data siklus datang dari sinkron site kota. +

+ ) : ( + <> +
+ +
+ {selected ? ( + + ) : ( +

Pilih tab siklus di atas.

+ )} + + )} +
+ ); +}; + +export default CycleTimeline; diff --git a/components/Dashboard.tsx b/components/Dashboard.tsx new file mode 100644 index 0000000..df0fa66 --- /dev/null +++ b/components/Dashboard.tsx @@ -0,0 +1,393 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { api, ApiError, errorMessage } from '../services/apiClient.ts'; +import type { + AIInsight, + ChickenCounting, + ChickenWeight, + Karung, + KPI, + LatestAvg, + ManualInput, +} from '../types/api.ts'; +import type { View } from '../types/common.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import KpiCard, { type KpiCardModel, type KpiTrendPoint } from './KpiCard.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from './ui/Feedback.tsx'; +import { + cycleDayForDate, + formatDateId, + formatDateRange, + formatNumber, + resolveCycleStatus, +} from '../utils/format.ts'; +import { isOnOrBeforeVisibleDate, throughVisibleDate } from '../utils/visibility.ts'; +import { getCountingAccuracyWarning } from '../utils/countingAccuracyWarning.ts'; +import DashboardReportCtas from './dashboard/DashboardReportCtas.tsx'; +import ReportPreviewOverlay from './dashboard/ReportPreviewOverlay.tsx'; +import CountingAccuracyWarningBanner from './counting/CountingAccuracyWarningBanner.tsx'; +import PendingCloseQueue from './PendingCloseQueue.tsx'; +import KandangRankingTop5 from './dashboard/KandangRankingTop5.tsx'; +import type { DashboardReportType } from '../types/dashboardReport.ts'; + +type Props = { setView: (view: View) => void }; + +function chronological(rows: T[]): T[] { + return [...rows].reverse(); +} + +const Dashboard: React.FC = ({ setView }) => { + const { selectedCycle, selectedKandang, selectedSite } = useFarm(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [kpis, setKpis] = useState([]); + const [countings, setCountings] = useState([]); + const [manualInputs, setManualInputs] = useState([]); + const [weights, setWeights] = useState([]); + const [karung, setKarung] = useState(null); + const [latestAvg, setLatestAvg] = useState(null); + const [insights, setInsights] = useState([]); + const [reportOpen, setReportOpen] = useState(false); + const [reportType, setReportType] = useState('daily'); + + useEffect(() => { + if (!selectedCycle) { + setKpis([]); + setCountings([]); + setManualInputs([]); + setWeights([]); + setKarung(null); + setLatestAvg(null); + setInsights([]); + return; + } + const cycleId = selectedCycle.id; + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const [kpiRows, countingRows, manualRows, weightRows, insightRows] = await Promise.all([ + api.kpis.list({ cycle_id: cycleId }), + api.countings.list({ cycle_id: cycleId }), + api.manualInputs.list({ cycle_id: cycleId }), + api.weights.list({ cycle_id: cycleId }), + api.insights.list({ cycle_id: cycleId }), + ]); + let latestKarung: Karung | null = null; + try { + latestKarung = await api.karungs.latest({ cycle_id: cycleId }); + } catch (err) { + if (!(err instanceof ApiError && err.status === 404)) throw err; + } + let avg: LatestAvg | null = null; + try { + avg = await api.weights.latestAvg({ cycle_id: cycleId }); + } catch (err) { + if (!(err instanceof ApiError && err.status === 404)) throw err; + } + if (cancelled) return; + setKpis(kpiRows); + setCountings(countingRows); + setManualInputs(manualRows); + setWeights(weightRows); + setKarung(latestKarung); + setLatestAvg(avg); + setInsights(insightRows); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedCycle]); + + const cards: KpiCardModel[] = useMemo(() => { + // Countings/weights APIs are real-time; KPI cards still honor publish cutoff. + const visibleThrough = selectedCycle?.visible_through_date; + const visibleKpis = throughVisibleDate(kpis, visibleThrough); + const visibleCountings = throughVisibleDate(countings, visibleThrough); + const visibleWeights = throughVisibleDate(weights, visibleThrough); + const visibleLatestAvg = + latestAvg && isOnOrBeforeVisibleDate(latestAvg.date, visibleThrough) ? latestAvg : null; + const visibleKarung = + karung && isOnOrBeforeVisibleDate(karung.date, visibleThrough) ? karung : null; + + const latest = visibleKpis[0]; + const startDate = selectedCycle?.start_date; + const trendLabel = (isoDate: string): string => { + const day = startDate ? cycleDayForDate(startDate, isoDate) : 0; + return `Hari ${day} · ${formatDateId(isoDate)}`; + }; + const fcrTrend: KpiTrendPoint[] = chronological(visibleKpis).map((row) => ({ + value: row.fcr, + label: trendLabel(row.date), + })); + const eefTrend: KpiTrendPoint[] = chronological(visibleKpis).map((row) => ({ + value: row.eef, + label: trendLabel(row.date), + })); + const mortalityTrend: KpiTrendPoint[] = chronological(visibleCountings).map((row) => ({ + value: row.mortality_count, + label: trendLabel(row.date), + })); + const mortalityToday = latest?.mortality ?? visibleCountings[0]?.mortality_count ?? null; + const weightTrend: KpiTrendPoint[] = chronological(visibleWeights).map((row) => ({ + value: row.average_weight, + label: trendLabel(row.date), + })); + const age = selectedCycle?.current_day ?? latest?.age ?? null; + return [ + { + key: 'umur', + title: 'Umur', + value: age, + unit: 'hari', + icon: '📅', + status: age == null ? 'na' : 'ok', + }, + { + key: 'mortality', + title: 'Mortalitas', + value: mortalityToday, + unit: 'ekor', + icon: '📉', + trend: mortalityTrend, + status: mortalityToday == null ? 'na' : 'ok', + targetView: 'dataManagement', + }, + { + key: 'karung', + title: 'Karung Dituang', + value: visibleKarung?.feed_use_today ?? visibleKarung?.out_today ?? null, + unit: 'karung', + icon: '🛢️', + status: visibleKarung ? 'ok' : 'na', + targetView: 'feedSackCounting', + }, + { + key: 'weight', + title: 'Berat AVG', + value: visibleLatestAvg?.average_weight ?? visibleWeights[0]?.average_weight ?? null, + unit: 'gram', + icon: '⚖️', + trend: weightTrend, + status: visibleLatestAvg || visibleWeights[0] ? 'ok' : 'na', + targetView: 'weightMonitoring', + }, + { + key: 'fcr', + title: 'FCR', + value: latest?.fcr ?? null, + unit: '', + icon: '📈', + trend: fcrTrend, + status: latest ? 'ok' : 'na', + targetView: 'fcrDashboard', + }, + { + key: 'eef', + title: 'EEF', + value: latest?.eef ?? null, + unit: '', + icon: '🎯', + trend: eefTrend, + status: latest ? 'ok' : 'na', + targetView: 'eefDashboard', + }, + ]; + }, [kpis, countings, weights, karung, latestAvg, selectedCycle]); + + const countingAccuracyWarning = useMemo(() => { + if (!selectedCycle) return null; + return getCountingAccuracyWarning({ + cycle: selectedCycle, + countings, + kpis, + manualInputs, + }); + }, [selectedCycle, countings, kpis, manualInputs]); + + if (!selectedCycle) { + return ( +
+ + setView('kandangSettings')} /> + +
+ ); + } + + const feedTotal = karung?.feed_use_total ?? kpis[0]?.feed_total ?? 0; + const feedWeightKg = feedTotal * 50; + const feedInitialBalance = selectedCycle?.feed_initial_balance ?? 0; + const feedInTotal = (karung?.in_total ?? 0) + feedInitialBalance; + const feedOutTotal = karung?.out_total ?? 0; + const feedSaldo = feedInTotal - feedTotal - feedOutTotal; + const feedSaldoColor = + feedSaldo > 0 ? 'text-green-600' : feedSaldo < 0 ? 'text-red-600' : 'text-gray-600'; + const cycleStatus = resolveCycleStatus(selectedCycle); + + return ( +
+ +
+ + { + setReportType('daily'); + setReportOpen(true); + }} + onOpenEndCycle={() => { + setReportType('end_cycle'); + setReportOpen(true); + }} + /> +
+ {error && ( +
+ {error} +
+ )} + {countingAccuracyWarning && ( + + )} + {loading ? ( + + ) : ( + <> +
+ {cards.map((card) => ( + setView(card.targetView as View) : undefined} + /> + ))} +
+
+
+
+ +
+
+

Total Pakan

+

Kumulatif karung pakan sejak awal siklus

+
+
+
+
+
+
+ +

Total Karung Tuang

+
+

{formatNumber(feedTotal)}

+

karung

+
+
+
+ +

Total Karung Masuk

+
+

{formatNumber(feedInTotal)}

+

karung

+
+
+
+ +

Total Karung Keluar

+
+

{formatNumber(feedOutTotal)}

+

karung

+
+
+
+ +

Saldo Awal

+
+

+ {formatNumber(feedInitialBalance)} +

+

karung

+
+
+ +
+
+
+ +

Total Berat Pakan

+
+

{formatNumber(feedWeightKg)}

+

kg

+
+
+
+ +

Saldo Karung Pakan

+
+

+ {formatNumber(feedSaldo)} +

+

karung

+
+
+
+
+ +
+

AI Insight

+ {insights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {insights.slice(0, 4).map((item) => ( +
+
+
+

+ {item.section} +

+

+ {item.alert || 'Insight'} +

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + )} + setReportOpen(false)} + /> +
+ ); +}; + +export default Dashboard; diff --git a/components/EefDashboardPage.tsx b/components/EefDashboardPage.tsx new file mode 100644 index 0000000..af59bc0 --- /dev/null +++ b/components/EefDashboardPage.tsx @@ -0,0 +1,471 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { + CartesianGrid, + Line, + LineChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import { api, errorMessage } from '../services/apiClient.ts'; +import type { AIInsight, KPI } from '../types/api.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from './ui/Feedback.tsx'; +import { formatNumber, formatRatio } from '../utils/format.ts'; + +type EefRow = { + day: number; + chickenLifePercentage: number | null; + averageHarvestBw: number | null; + averageHarvestDay: number | null; + fcr: number | null; + eef: number | null; +}; + +type TrendPoint = { day: number; eef: number | null }; +type SupportPoint = { + day: number; + chickenLifePercentage: number | null; + averageHarvestBw: number | null; + averageHarvestDay: number | null; + fcr: number | null; +}; + +const formatThreeDecimal = (value: number | null): string => + value == null ? 'N/A' : formatRatio(value, 3); + +const formatNum = (value: number | null | undefined, maxDecimals = 0): string => + value == null || !Number.isFinite(Number(value)) + ? 'N/A' + : formatNumber(Number(value), maxDecimals, 0, true); + +const StatCard: React.FC<{ title: string; value: string; unit: string }> = ({ + title, + value, + unit, +}) => ( +
+

{title}

+
+ {value} + {unit} +
+
+); + +const EefTrendChart: React.FC<{ data: TrendPoint[] }> = ({ data }) => ( +
+

Grafik EEF

+
+ {data.length === 0 ? ( +
+ Tidak ada data EEF tersedia. +
+ ) : ( + + + + + formatNum(Number(value), 0)} + width={60} + domain={[0, 'dataMax + 20']} + label={{ value: 'EEF', angle: -90, position: 'insideLeft' }} + /> + [formatThreeDecimal(Number(value)), 'EEF']} + labelFormatter={(label) => `Hari ${label}`} + /> + + + + )} +
+
+); + +const SupportingMetricChart: React.FC<{ + title: string; + data: SupportPoint[]; + dataKey: keyof Omit; + unit: string; + stroke: string; + maximumFractionDigits?: number; + valueFormatter?: (value: number) => string; +}> = ({ title, data, dataKey, unit, stroke, maximumFractionDigits = 0, valueFormatter }) => ( +
+

{title}

+
+ {data.length === 0 ? ( +
+ Tidak ada data tersedia. +
+ ) : ( + + + + + + valueFormatter + ? valueFormatter(Number(value)) + : formatNum(Number(value), maximumFractionDigits) + } + width={70} + /> + { + const formatted = valueFormatter + ? valueFormatter(Number(value)) + : formatNum(Number(value), maximumFractionDigits); + return [`${formatted}${unit ? ` ${unit}` : ''}`, title]; + }} + labelFormatter={(label) => `Hari ${label}`} + /> + + + + )} +
+
+); + +const EefDashboardPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle } = useFarm(); + const [rows, setRows] = useState([]); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [refreshing, setRefreshing] = useState(false); + const [error, setError] = useState(null); + const [lastUpdated, setLastUpdated] = useState(null); + + const loadData = useCallback(async () => { + if (!selectedCycle) return; + setError(null); + try { + const [kpiRows, insightRows] = await Promise.all([ + api.kpis.list({ cycle_id: selectedCycle.id }), + api.insights.list({ cycle_id: selectedCycle.id }), + ]); + setRows(kpiRows); + setInsights(insightRows); + setLastUpdated(new Date()); + } catch (err) { + setError(errorMessage(err)); + } + }, [selectedCycle]); + + useEffect(() => { + if (!selectedCycle) { + setRows([]); + setInsights([]); + setLastUpdated(null); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + try { + await loadData(); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedCycle, loadData]); + + const handleRefresh = async () => { + setRefreshing(true); + try { + await loadData(); + } finally { + setRefreshing(false); + } + }; + + const eefRows = useMemo( + () => + [...rows] + .sort((a, b) => a.age - b.age || a.date.localeCompare(b.date)) + .map((row) => ({ + day: row.age, + chickenLifePercentage: row.chicken_life_percentage, + averageHarvestBw: row.average_harvest_weight > 0 ? row.average_harvest_weight : null, + averageHarvestDay: row.average_harvest_day > 0 ? row.average_harvest_day : null, + fcr: row.fcr > 0 ? row.fcr : null, + eef: row.eef > 0 ? row.eef : null, + })), + [rows] + ); + + const trendData = useMemo( + () => eefRows.map((row) => ({ day: row.day, eef: row.eef })), + [eefRows] + ); + + const supportData = useMemo( + () => + eefRows.map((row) => ({ + day: row.day, + chickenLifePercentage: row.chickenLifePercentage, + averageHarvestBw: row.averageHarvestBw, + averageHarvestDay: row.averageHarvestDay, + fcr: row.fcr, + })), + [eefRows] + ); + + const getLatestValid = (key: K): EefRow[K] | null => { + for (let i = eefRows.length - 1; i >= 0; i--) { + const val = eefRows[i]?.[key]; + if (val !== null && val !== undefined && val !== 0 && String(val) !== '') { + return val; + } + } + return null; + }; + + const latestEef = getLatestValid('eef'); + + const eefInsights = useMemo(() => { + const matched = insights.filter((item) => { + const text = + `${item.section ?? ''} ${item.alert ?? ''} ${item.insight_text ?? ''}`.toLowerCase(); + return ( + text.includes('eef') || + text.includes('fcr') || + text.includes('hidup') || + text.includes('live') || + text.includes('panen') || + text.includes('bw') + ); + }); + return (matched.length > 0 ? matched : insights).slice(0, 4); + }, [insights]); + + if (!selectedCycle) return ; + + return ( +
+
+ } + /> + +
+ + {error && ( +
+ {error} +
+ )} + +
+

+ + AI Insight EEF +

+ {loading ? ( + + ) : eefInsights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {eefInsights.map((item) => ( +
+
+
+

{item.section}

+

{item.alert || 'Insight'}

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + {loading ? ( + + ) : ( +
+
+ + + + + +
+ + + +
+
+

Data Pendukung EEF

+ {lastUpdated && ( +

+ Update:{' '} + {lastUpdated.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' })} +

+ )} +
+ +
+

Grafik Data Pendukung

+
+ + + + formatThreeDecimal(value)} + /> +
+
+ +
+
+

Tabel Data Pendukung EEF

+
+
+ + + + + + + + + + + + + {eefRows.map((row) => ( + + + + + + + + + ))} + {eefRows.length === 0 && ( + + + + )} + +
UmurPersentase Ayam HidupBW Rata-rata PanenUmur Rata-rata PanenFCREEF
Hari {row.day} + {formatNum(row.chickenLifePercentage, 3)} + {row.chickenLifePercentage != null ? '%' : ''} + + {formatNum(row.averageHarvestBw, 2)} + {row.averageHarvestBw != null ? ' g' : ''} + + {formatNum(row.averageHarvestDay, 2)} + + {formatThreeDecimal(row.fcr)} + + {formatThreeDecimal(row.eef)} +
+ Tidak ada data EEF tersedia. +
+
+
+
+
+ )} +
+ ); +}; + +export default EefDashboardPage; diff --git a/components/FcrDashboardPage.tsx b/components/FcrDashboardPage.tsx new file mode 100644 index 0000000..1824d7e --- /dev/null +++ b/components/FcrDashboardPage.tsx @@ -0,0 +1,473 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { + CartesianGrid, + Line, + LineChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import { api, errorMessage } from '../services/apiClient.ts'; +import type { AIInsight, ChickenWeight, KPI } from '../types/api.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from './ui/Feedback.tsx'; +import { formatNumber, formatRatio } from '../utils/format.ts'; + +type FcrRow = { + day: number; + feedTotal: number; + iotWeight: number | null; + chickenLife: number; + harvestWeightKg: number; + fcr: number | null; +}; + +type TrendPoint = { day: number; fcr: number | null }; +type SupportPoint = { + day: number; + feedTotal: number; + iotWeight: number | null; + chickenLife: number; + harvestWeightKg: number; +}; + +const formatFcr = (value: number | null): string => (value == null ? 'N/A' : formatRatio(value, 3)); + +const formatNum = (value: number | null | undefined, maxDecimals = 0): string => + value == null || !Number.isFinite(Number(value)) + ? 'N/A' + : formatNumber(Number(value), maxDecimals, 0, true); + +const StatCard: React.FC<{ title: string; value: string; unit: string }> = ({ + title, + value, + unit, +}) => ( +
+

{title}

+
+ {value} + {unit} +
+
+); + +const FcrTrendChart: React.FC<{ data: TrendPoint[] }> = ({ data }) => ( +
+

Grafik FCR

+
+ {data.length === 0 ? ( +
+ Tidak ada data FCR tersedia. +
+ ) : ( + + + + + + [formatFcr(Number(value)), 'FCR']} + labelFormatter={(label) => `Hari ${label}`} + /> + + + + )} +
+
+); + +const SupportingMetricChart: React.FC<{ + title: string; + data: SupportPoint[]; + dataKey: keyof Omit; + unit: string; + stroke: string; + maximumFractionDigits?: number; +}> = ({ title, data, dataKey, unit, stroke, maximumFractionDigits = 0 }) => ( +
+

{title}

+
+ {data.length === 0 ? ( +
+ Tidak ada data tersedia. +
+ ) : ( + + + + + formatNum(Number(value), maximumFractionDigits)} + width={70} + /> + [ + `${formatNum(Number(value), maximumFractionDigits)} ${unit}`, + title, + ]} + labelFormatter={(label) => `Hari ${label}`} + /> + + + + )} +
+
+); + +const FcrDashboardPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle } = useFarm(); + const [rows, setRows] = useState([]); + const [weightRows, setWeightRows] = useState([]); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [refreshing, setRefreshing] = useState(false); + const [error, setError] = useState(null); + const [lastUpdated, setLastUpdated] = useState(null); + + const loadData = useCallback(async () => { + if (!selectedCycle) return; + setError(null); + try { + const [kpiRows, insightRows, weightList] = await Promise.all([ + api.kpis.list({ cycle_id: selectedCycle.id }), + api.insights.list({ cycle_id: selectedCycle.id }), + api.weights.list({ cycle_id: selectedCycle.id }), + ]); + setRows(kpiRows); + setInsights(insightRows); + setWeightRows(weightList); + setLastUpdated(new Date()); + } catch (err) { + setError(errorMessage(err)); + } + }, [selectedCycle]); + + useEffect(() => { + if (!selectedCycle) { + setRows([]); + setWeightRows([]); + setInsights([]); + setLastUpdated(null); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + try { + await loadData(); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedCycle, loadData]); + + const handleRefresh = async () => { + setRefreshing(true); + try { + await loadData(); + } finally { + setRefreshing(false); + } + }; + + const weightByAge = useMemo(() => { + const map = new Map(); + for (const weight of weightRows) { + if (weight.average_weight > 0 && !map.has(weight.age)) { + map.set(weight.age, weight.average_weight); + } + } + return map; + }, [weightRows]); + + const fcrRows = useMemo( + () => + [...rows] + .sort((a, b) => a.age - b.age || a.date.localeCompare(b.date)) + .map((row) => ({ + day: row.age, + feedTotal: row.feed_total, + iotWeight: weightByAge.get(row.age) ?? null, + chickenLife: row.chicken_life, + harvestWeightKg: row.harvest_weight_total / 1000, + fcr: row.fcr > 0 ? row.fcr : null, + })), + [rows, weightByAge] + ); + + const trendData = useMemo( + () => fcrRows.map((row) => ({ day: row.day, fcr: row.fcr })), + [fcrRows] + ); + + const supportData = useMemo( + () => + fcrRows.map((row) => ({ + day: row.day, + feedTotal: row.feedTotal, + iotWeight: row.iotWeight, + chickenLife: row.chickenLife, + harvestWeightKg: row.harvestWeightKg, + })), + [fcrRows] + ); + + const getLatestValid = (key: K): FcrRow[K] | null => { + for (let i = fcrRows.length - 1; i >= 0; i--) { + const val = fcrRows[i]?.[key]; + if (val !== null && val !== undefined && val !== 0 && String(val) !== '') { + return val; + } + } + return null; + }; + + const latestFcr = getLatestValid('fcr'); + const latestIotWeight = getLatestValid('iotWeight'); + + const fcrInsights = useMemo(() => { + const matched = insights.filter((item) => { + const text = + `${item.section ?? ''} ${item.alert ?? ''} ${item.insight_text ?? ''}`.toLowerCase(); + return ( + text.includes('fcr') || + text.includes('pakan') || + text.includes('feed') || + text.includes('konversi') || + text.includes('panen') + ); + }); + return (matched.length > 0 ? matched : insights).slice(0, 4); + }, [insights]); + + if (!selectedCycle) return ; + + return ( +
+
+ } + /> + +
+ + {error && ( +
+ {error} +
+ )} + +
+

+ + AI Insight FCR +

+ {loading ? ( + + ) : fcrInsights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {fcrInsights.map((item) => ( +
+
+
+

{item.section}

+

{item.alert || 'Insight'}

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + {loading ? ( + + ) : ( +
+
+ + + + + +
+ + + +
+
+

Data Pendukung FCR

+ {lastUpdated && ( +

+ Update:{' '} + {lastUpdated.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' })} +

+ )} +
+ +
+

Grafik Data Pendukung

+
+ + + + +
+
+ +
+
+

Tabel Data Pendukung FCR

+
+
+ + + + + + + + + + + + + {fcrRows.map((row) => ( + + + + + + + + + ))} + {fcrRows.length === 0 && ( + + + + )} + +
UmurTotal PakanBobot IoTAyam HidupTotal Bobot PanenFCR
Hari {row.day} + {formatNum(row.feedTotal)} karung + + {formatNum(row.iotWeight, 2)} + {row.iotWeight != null ? ' g' : ''} + + {formatNum(row.chickenLife)} ekor + + {formatNum(row.harvestWeightKg, 1)} kg + + {formatFcr(row.fcr)} +
+ Tidak ada data FCR tersedia. +
+
+
+
+
+ )} +
+ ); +}; + +export default FcrDashboardPage; diff --git a/components/FeedSackCountingPage.tsx b/components/FeedSackCountingPage.tsx new file mode 100644 index 0000000..858848a --- /dev/null +++ b/components/FeedSackCountingPage.tsx @@ -0,0 +1,321 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { api, errorMessage } from '../services/apiClient.ts'; +import type { AIInsight, Cycle, Karung, ManualInput } from '../types/api.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, Spinner } from './ui/Feedback.tsx'; +import { addDaysIso, cycleDayForDate, formatDateId, resolveCycleStatus, todayIso } from '../utils/format.ts'; +import FeedStats from './feedSack/FeedStats.tsx'; +import FeedSaldoCard from './feedSack/FeedSaldoCard.tsx'; +import FeedTrendChart from './feedSack/FeedTrendChart.tsx'; +import FeedDailySummaryTable from './feedSack/FeedDailySummaryTable.tsx'; +import InitialBalanceCard from './feedSack/InitialBalanceCard.tsx'; + +const FeedSackCountingPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle, selectedKandang, selectedSite, cycles, setSelectedCycleId } = + useFarm(); + const [rows, setRows] = useState([]); + const [manualRows, setManualRows] = useState([]); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [syncing, setSyncing] = useState(false); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + const [showCyclePicker, setShowCyclePicker] = useState(false); + + const reload = useCallback(async (cycleId: number) => { + setLoading(true); + setError(null); + try { + const [karungRows, insightRows, manualList] = await Promise.all([ + api.karungs.list({ cycle_id: cycleId }), + api.insights.list({ cycle_id: cycleId }), + api.manualInputs.list({ cycle_id: cycleId }), + ]); + setRows(karungRows); + setInsights(insightRows); + setManualRows(manualList); + } catch (err) { + setError(errorMessage(err)); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + if (!selectedCycle) { + setRows([]); + setInsights([]); + setManualRows([]); + return; + } + void reload(selectedCycle.id); + }, [selectedCycle, reload]); + + const sortedRows = useMemo(() => [...rows].sort((a, b) => a.date.localeCompare(b.date)), [rows]); + const latest = sortedRows[sortedRows.length - 1] ?? null; + + const sortedManualRows = useMemo( + () => [...manualRows].sort((a, b) => a.date.localeCompare(b.date)), + [manualRows] + ); + const visibleThrough = selectedCycle?.visible_through_date; + // Display date follows the latest IoT snapshot; without any snapshot, fall back to today. + // Manual cards only use a same-date row — never fall back to an older day. + const displayDate = latest?.date ?? visibleThrough ?? todayIso(); + const latestManual = sortedManualRows.find((row) => row.date === displayDate) ?? null; + const currentDay = useMemo(() => { + if (!selectedCycle) return 0; + const rawDay = cycleDayForDate(selectedCycle.start_date, displayDate); + return Math.min(rawDay, Math.max(0, selectedCycle.total_days - 1)); + }, [selectedCycle, displayDate]); + + const handleSync = useCallback(async () => { + if (!selectedCycle) return; + setSyncing(true); + setError(null); + setNotice(null); + try { + await api.karungs.request({ cycle_id: selectedCycle.id, section: 'today' }); + setNotice('Sinkron karung-web-admin berhasil.'); + await reload(selectedCycle.id); + } catch (err) { + setError(errorMessage(err)); + } finally { + setSyncing(false); + } + }, [selectedCycle, reload]); + + const sortedCycles = useMemo(() => { + return [...cycles].sort( + (a, b) => new Date(b.start_date).getTime() - new Date(a.start_date).getTime() + ); + }, [cycles]); + + const formatCycleDateRange = (cycle: Cycle) => { + const start = formatDateId(cycle.start_date); + if (cycle.end_date) return `${start} - ${formatDateId(cycle.end_date)}`; + return `${start} - ${formatDateId(addDaysIso(cycle.start_date, cycle.total_days))}`; + }; + + const lastUpdated = useMemo(() => { + if (!latest) return null; + const timestamp = latest.updated_at || latest.created_at; + if (!timestamp) return null; + const date = new Date(timestamp); + if (Number.isNaN(date.getTime())) return null; + return `${date.toLocaleDateString('id-ID', { + day: 'numeric', + month: 'short', + year: 'numeric', + })} ${date.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' })}`; + }, [latest]); + + if (!selectedCycle) return ; + + const cycleStatus = resolveCycleStatus(selectedCycle); + + return ( +
+ {/* Page Title */} +
+
+ +
+
+

Hitung Karung

+

Monitoring karung masuk dan karung dituang per hari

+ {lastUpdated && ( +

+ + Terakhir diperbarui: {lastUpdated} +

+ )} +
+
+ +
+
+ + {/* Cycle Selector */} +
+
+ + + {/* Cycle Picker Dropdown */} + {showCyclePicker && ( +
+ {sortedCycles.map((cycle) => { + const itemStatus = resolveCycleStatus(cycle); + return ( + + ); + })} +
+ )} +
+
+ + {error && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + + {loading ? ( + + ) : ( +
+ {/* AI Insight */} +
+

+ + AI Insight Hitung Karung +

+ {insights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {insights.slice(0, 4).map((item) => ( +
+
+
+

+ {item.section} +

+

+ {item.alert || 'Insight'} +

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + {/* Saldo Awal */} + + + {/* Ringkasan stats */} + + + {/* Saldo Karung */} + + + {/* Tren harian */} + + + {/* Rincian harian */} + +
+ )} + +
+ Sumber data: karung-web-admin · {selectedSite ? selectedSite.site_name : ''} + {selectedKandang ? ` · ${selectedKandang.kandang_name}` : ''} +
+
+ ); +}; + +export default FeedSackCountingPage; diff --git a/components/Header.tsx b/components/Header.tsx new file mode 100644 index 0000000..2006c9e --- /dev/null +++ b/components/Header.tsx @@ -0,0 +1,217 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { useAuth } from '../context/AuthContext.tsx'; +import { useFarm } from '../context/FarmContext.tsx'; +import type { UserStatus } from '../types/api.ts'; +import { formatDateId, resolveCycleStatus } from '../utils/format.ts'; + +const ROLE_LABELS: Record = { + inactive: 'Inactive', + gm: 'GM', + gm_admin: 'GM Admin', + buh: 'BUH', + bu_admin: 'BU Admin', + director: 'Director', + director_admin: 'Director Admin', + account_admin: 'Account Admin', + superuser: 'Superuser', +}; + +type HeaderProps = { + onToggleSidebar: () => void; + isTimelineVisible: boolean; + onToggleTimeline: () => void; +}; + +const Header: React.FC = ({ + onToggleSidebar, + isTimelineVisible, + onToggleTimeline, +}) => { + const { user, logout } = useAuth(); + const { + sites, + kandangs, + cycles, + selectedSiteId, + selectedKandangId, + selectedCycleId, + setSelectedSiteId, + setSelectedKandangId, + setSelectedCycleId, + } = useFarm(); + const [open, setOpen] = useState(false); + const [gmFilter, setGmFilter] = useState<'all' | number>('all'); + const dropdownRef = useRef(null); + + const isBuh = user?.status === 'buh' || user?.status === 'bu_admin'; + + const gmOptions = useMemo(() => { + const byId = new Map(); + for (const site of sites) { + if (!byId.has(site.user)) { + byId.set(site.user, site.owner_name ?? `GM #${site.user}`); + } + } + return [...byId.entries()] + .map(([id, name]) => ({ id, name })) + .sort((a, b) => a.name.localeCompare(b.name)); + }, [sites]); + + const visibleSites = useMemo(() => { + if (!isBuh || gmFilter === 'all') return sites; + return sites.filter((site) => site.user === gmFilter); + }, [gmFilter, isBuh, sites]); + + useEffect(() => { + if (!isBuh || gmFilter === 'all') return; + if (selectedSiteId == null) return; + const stillVisible = visibleSites.some((site) => site.id === selectedSiteId); + if (!stillVisible) { + setSelectedSiteId(visibleSites[0]?.id ?? null); + } + }, [gmFilter, isBuh, selectedSiteId, setSelectedSiteId, visibleSites]); + + useEffect(() => { + const onClick = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setOpen(false); + } + }; + document.addEventListener('mousedown', onClick); + return () => document.removeEventListener('mousedown', onClick); + }, []); + + if (!user) return null; + + return ( +
+
+
+ + {isBuh && gmOptions.length > 0 && ( +
+ + +
+ )} +
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+ + {open && ( +
+
+

{user.user_name}

+

{ROLE_LABELS[user.status]}

+
+ +
+ )} +
+
+
+
+ ); +}; + +export default Header; diff --git a/components/IotPanelPage.tsx b/components/IotPanelPage.tsx new file mode 100644 index 0000000..61fc430 --- /dev/null +++ b/components/IotPanelPage.tsx @@ -0,0 +1,595 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { + CartesianGrid, + Line, + LineChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import { api, errorMessage } from '../services/apiClient.ts'; +import type { AIInsight, Flock, PanelIoT } from '../types/api.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from './ui/Feedback.tsx'; +import { cycleDayForDate, formatDateId, formatDateRange, formatNumber } from '../utils/format.ts'; +import { computeExperienceCalc } from './iotPanel/chillFactor.ts'; +import IotPanelChillFactorCard from './iotPanel/IotPanelChillFactorCard.tsx'; +import IotPanelExperienceTempCard from './iotPanel/IotPanelExperienceTempCard.tsx'; + +const cardClass = 'rounded-xl border border-slate-200 bg-white p-4 shadow-sm'; + +const SECONDARY_CHARTS = [ + { key: 'humidity', label: 'Kelembapan', unit: ' %', color: '#3b82f6' }, + { key: 'wind', label: 'Angin', unit: ' m/s', color: '#6366f1' }, + { key: 'water', label: 'Air', unit: ' L', color: '#06b6d4' }, +] as const; + +const display = (value: number | null | undefined, suffix = '') => + value == null || !Number.isFinite(Number(value)) + ? 'N/A' + : `${formatNumber(Number(value))}${suffix}`; + +const formatTime = (iso: string | null | undefined): string => { + if (!iso) return '--'; + const date = new Date(iso); + if (Number.isNaN(date.getTime())) return iso; + return date.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' }); +}; + +type DaySummary = { + count: number; + temp: number; + minTemp: number; + maxTemp: number; + experienceTemp: number; + minExp: number; + maxExp: number; + humidity: number; + windSpeed: number; + waterTotal: number; +}; + +const IotPanelPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle, selectedKandang, selectedSite } = useFarm(); + const [flocks, setFlocks] = useState([]); + const [selectedFlockId, setSelectedFlockId] = useState(null); + const [dates, setDates] = useState([]); + const [selectedDate, setSelectedDate] = useState(''); + const [dayRows, setDayRows] = useState([]); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [refreshing, setRefreshing] = useState(false); + const [error, setError] = useState(null); + const [refreshToken, setRefreshToken] = useState(0); + const [selectedChartKey, setSelectedChartKey] = useState<'humidity' | 'wind' | 'water' | null>( + null + ); + + useEffect(() => { + if (!selectedChartKey) return; + const onKey = (event: KeyboardEvent) => { + if (event.key === 'Escape') setSelectedChartKey(null); + }; + window.addEventListener('keydown', onKey); + return () => window.removeEventListener('keydown', onKey); + }, [selectedChartKey]); + + useEffect(() => { + if (!selectedKandang) { + setFlocks([]); + setSelectedFlockId(null); + setDates([]); + setSelectedDate(''); + setDayRows([]); + setInsights([]); + return; + } + let cancelled = false; + (async () => { + setError(null); + try { + const data = await api.flocks.list({ kandang_id: selectedKandang.id }); + if (cancelled) return; + setFlocks(data); + setSelectedFlockId((previous) => + previous && data.some((flock) => flock.id === previous) ? previous : (data[0]?.id ?? null) + ); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedKandang, refreshToken]); + + useEffect(() => { + if (!selectedCycle || selectedFlockId == null) { + setDates([]); + setSelectedDate(''); + setDayRows([]); + setInsights([]); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const [dateList, insightRows] = await Promise.all([ + api.panelIot.dates({ cycle_id: selectedCycle.id, flock_id: selectedFlockId }), + api.insights.list({ cycle_id: selectedCycle.id }), + ]); + if (cancelled) return; + const sortedDates = [...dateList].sort(); + setDates(sortedDates); + setInsights(insightRows); + setSelectedDate((previous) => + previous && sortedDates.includes(previous) + ? previous + : (sortedDates[sortedDates.length - 1] ?? '') + ); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedCycle, selectedFlockId, refreshToken]); + + useEffect(() => { + if (!selectedCycle || selectedFlockId == null || !selectedDate) { + setDayRows([]); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const data = await api.panelIot.list({ + cycle_id: selectedCycle.id, + flock_id: selectedFlockId, + date: selectedDate, + }); + if (!cancelled) { + const sorted = [...data].sort((a, b) => + (a.timestamp ?? a.date).localeCompare(b.timestamp ?? b.date) + ); + setDayRows(sorted); + } + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedCycle, selectedFlockId, selectedDate, refreshToken]); + + const summary = useMemo(() => { + if (dayRows.length === 0) return null; + const sorted = [...dayRows].sort((a, b) => + (a.timestamp ?? a.date).localeCompare(b.timestamp ?? b.date) + ); + const min = (key: keyof PanelIoT) => Math.min(...sorted.map((row) => Number(row[key]))); + const max = (key: keyof PanelIoT) => Math.max(...sorted.map((row) => Number(row[key]))); + const last = sorted[sorted.length - 1]!; + return { + count: sorted.length, + temp: last.average_temperature, + minTemp: min('average_temperature'), + maxTemp: max('average_temperature'), + experienceTemp: last.experience_temperature, + minExp: min('experience_temperature'), + maxExp: max('experience_temperature'), + humidity: last.humidity, + windSpeed: last.wind_speed, + waterTotal: last.water_total, + }; + }, [dayRows]); + + const chartRows = useMemo( + () => + [...dayRows] + .sort((a, b) => (a.timestamp ?? a.date).localeCompare(b.timestamp ?? b.date)) + .map((row) => ({ + time: formatTime(row.timestamp), + average: row.average_temperature, + experience: row.experience_temperature, + humidity: row.humidity, + wind: row.wind_speed, + water: row.water_total, + })), + [dayRows] + ); + + const dayAge = selectedDate + ? cycleDayForDate(selectedCycle?.start_date ?? '', selectedDate) + : null; + const experienceCalc = useMemo( + () => + computeExperienceCalc({ + averageTemp: summary?.temp, + windSpeed: summary?.windSpeed, + humidity: summary?.humidity, + dayAge, + }), + [summary, dayAge] + ); + + const iotInsights = useMemo(() => { + const matched = insights.filter((item) => { + const text = + `${item.section ?? ''} ${item.alert ?? ''} ${item.insight_text ?? ''}`.toLowerCase(); + return ( + text.includes('iot') || + text.includes('suhu') || + text.includes('kelembapan') || + text.includes('humidity') || + text.includes('temperature') || + text.includes('lingkungan') + ); + }); + return (matched.length > 0 ? matched : insights).slice(0, 4); + }, [insights]); + + const refresh = () => { + setRefreshing(true); + setRefreshToken((token) => token + 1); + window.setTimeout(() => setRefreshing(false), 500); + }; + + if (!selectedCycle) return ; + + return ( +
+ } + actions={ +
+ + +
+ } + /> + + {error && {error}} + {loading && dayRows.length === 0 ? ( + + ) : summary ? ( + <> +
+

+ + AI Insight Panel IoT +

+ {iotInsights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {iotInsights.map((item) => ( +
+
+
+

+ {item.section} +

+

+ {item.alert || 'Insight'} +

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ +
+ + + + setSelectedDate(event.target.value)} + className="rounded-lg border border-slate-300 bg-white px-2 py-1.5 text-sm text-slate-700 focus:ring-2 focus:ring-red-500 focus:border-red-500" + /> + + {summary.count} pembacaan +
+ +
+
+
+
+
+

+ + Suhu Rata-Rata +

+

+ {display(summary.temp, ' °C')} +

+

+ {display(summary.minTemp, ' °C')} – {display(summary.maxTemp, ' °C')} +

+
+
+

+ + Experience Suhu +

+

+ {display(summary.experienceTemp, ' °C')} +

+

+ {display(summary.minExp, ' °C')} – {display(summary.maxExp, ' °C')} +

+
+
+
+ +
+
+ {[ + { + label: 'Kelembapan', + value: display(summary.humidity, ' %'), + icon: 'fa-droplet', + color: 'text-blue-500', + chartKey: 'humidity', + }, + { + label: 'Angin', + value: display(summary.windSpeed, ' m/s'), + icon: 'fa-wind', + color: 'text-indigo-500', + chartKey: 'wind', + }, + { + label: 'Air total', + value: display(summary.waterTotal, ' L'), + icon: 'fa-water', + color: 'text-cyan-500', + chartKey: 'water', + }, + { + label: 'Umur', + value: dayAge == null ? 'N/A' : `${dayAge} hari`, + icon: 'fa-dove', + color: 'text-amber-600', + }, + { + label: 'Tanggal', + value: formatDateId(selectedDate), + icon: 'fa-calendar-day', + color: 'text-slate-500', + }, + { + label: 'Flock', + value: + flocks.find((flock) => flock.id === selectedFlockId)?.flock_name ?? 'N/A', + icon: 'fa-warehouse', + color: 'text-slate-500', + }, + ].map((tile) => { + const inner = ( + <> +

+ + {tile.label} +

+

{tile.value}

+ + ); + if (!tile.chartKey) { + return ( +
+ {inner} +
+ ); + } + return ( + + ); + })} +
+
+ + +
+ +
+
+
+
+

Histori Suhu Harian

+

+ + + Garis merah = suhu rata-rata + + + + Garis biru = experience suhu + +

+
+ + {formatDateId(selectedDate)} + +
+
+ + + + + + [ + `${formatNumber(Number(value))} °C`, + name as string, + ]} + /> + + + + +
+
+ + +
+
+ + ) : ( +
+

+ Belum ada data panel IoT untuk flock ini. +

+
+ )} + + {selectedChartKey && + (() => { + const chart = SECONDARY_CHARTS.find((item) => item.key === selectedChartKey)!; + const latestPoint = chartRows[chartRows.length - 1]; + return ( +
setSelectedChartKey(null)} + > +
event.stopPropagation()} + > +
+
+

{chart.label}

+

+ Pembacaan sepanjang hari · {formatDateId(selectedDate)} +

+
+
+ + Terakhir: {display(latestPoint?.[chart.key], chart.unit)} + + +
+
+
+ + + + + + [ + `${formatNumber(Number(value))}${chart.unit}`, + name as string, + ]} + /> + + + +
+
+
+ ); + })()} +
+ ); +}; + +export default IotPanelPage; diff --git a/components/KandangRankingPage.tsx b/components/KandangRankingPage.tsx new file mode 100644 index 0000000..0394619 --- /dev/null +++ b/components/KandangRankingPage.tsx @@ -0,0 +1,208 @@ +import React, { useEffect, useState } from 'react'; +import { errorMessage } from '../services/apiClient.ts'; +import type { View } from '../types/common.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from './ui/Feedback.tsx'; +import { formatDateRange, formatRatio } from '../utils/format.ts'; +import { + loadKandangRanking, + type KandangRankingRow, +} from '../utils/kandangRanking.ts'; + +type ScopeMode = 'selected' | 'all'; + +type Props = { + setView: (view: View) => void; +}; + +const MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => i + 1); + +const formatMetric = (value: number | null): string => + value == null ? 'N/A' : formatRatio(value, 3); + +const KandangRankingPage: React.FC = ({ setView }) => { + const { + sites, + selectedSite, + selectedSiteId, + setSelectedSiteId, + setSelectedKandangId, + setSelectedCycleId, + } = useFarm(); + + const [scope, setScope] = useState('selected'); + const [months, setMonths] = useState(3); + const [rows, setRows] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const needsSite = scope === 'selected' && selectedSiteId == null; + + useEffect(() => { + if (needsSite) { + setRows([]); + setError(null); + setLoading(false); + return; + } + + const targetSites = + scope === 'all' ? sites : selectedSite ? [selectedSite] : []; + if (targetSites.length === 0) { + setRows([]); + return; + } + + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const next = await loadKandangRanking({ sites: targetSites, months }); + if (!cancelled) setRows(next); + } catch (err) { + if (!cancelled) { + setError(errorMessage(err)); + setRows([]); + } + } finally { + if (!cancelled) setLoading(false); + } + })(); + + return () => { + cancelled = true; + }; + }, [scope, months, sites, selectedSite, selectedSiteId, needsSite]); + + const openEef = (row: KandangRankingRow) => { + setSelectedSiteId(row.siteId); + setSelectedKandangId(row.kandangId); + setSelectedCycleId(row.cycleId); + setView('eefDashboard'); + }; + + if (needsSite) { + return ( +
+ + setView('kandangSettings')} /> +
+ ); + } + + const showSiteColumn = scope === 'all'; + + return ( +
+
+ +
+
+ + +
+ +
+
+ + {error && ( +
+ {error} +
+ )} + + {loading ? ( + + ) : rows.length === 0 ? ( + Tidak ada siklus tertutup dalam rentang ini. + ) : ( +
+ + + + + {showSiteColumn && } + + + + + + + + + {rows.map((row) => ( + openEef(row)} + > + + {showSiteColumn && ( + + )} + + + + + + + ))} + +
RankSiteKandangPeriodeHariEEFFCR
+ {row.rank > 0 ? row.rank : '—'} + {row.siteName}{row.kandangName} + {formatDateRange(row.startDate, row.endDate)} + {row.totalDays || '—'} + {formatMetric(row.eef)} + {formatMetric(row.fcr)}
+
+ )} +
+ ); +}; + +export default KandangRankingPage; diff --git a/components/KpiCard.tsx b/components/KpiCard.tsx new file mode 100644 index 0000000..442e353 --- /dev/null +++ b/components/KpiCard.tsx @@ -0,0 +1,129 @@ +import React, { useMemo } from 'react'; +import { Line, LineChart, ResponsiveContainer, Tooltip, XAxis } from 'recharts'; +import { formatNumber, formatRatio } from '../utils/format.ts'; +import type { View } from '../types/common.ts'; + +export type KpiStatus = 'ok' | 'warning' | 'critical' | 'na'; + +export type KpiTrendPoint = { + value: number; + /** Tooltip label, e.g. ``Hari 0 · 2 Sep 2026``. */ + label: string; +}; + +export type KpiCardModel = { + key: string; + title: string; + value: number | null; + unit: string; + icon: string; + trend?: KpiTrendPoint[]; + status: KpiStatus; + targetView?: View; +}; + +const statusStyles: Record = { + ok: { bg: 'bg-green-100', text: 'text-green-800', icon: 'text-green-600', line: '#16a34a' }, + warning: { + bg: 'bg-yellow-100', + text: 'text-yellow-800', + icon: 'text-yellow-600', + line: '#f59e0b', + }, + critical: { bg: 'bg-red-100', text: 'text-red-800', icon: 'text-red-600', line: '#dc2626' }, + na: { bg: 'bg-blue-50', text: 'text-blue-900', icon: 'text-blue-600', line: '#3b82f6' }, +}; + +type Props = Omit & { + onClick?: () => void; + isLoading?: boolean; +}; + +const KpiCard: React.FC = ({ + title, + value, + unit, + icon, + trend, + status, + onClick, + isLoading = false, +}) => { + const isNA = value === null; + const styles = isNA ? statusStyles.na : statusStyles[status]; + const trendData = useMemo( + () => (trend ?? []).map((point) => ({ name: point.label, value: point.value })), + [trend] + ); + + const displayValue = () => { + if (value === null) return 'N/A'; + if (title.toUpperCase().includes('FCR') || title.toUpperCase().includes('EEF')) { + return formatRatio(value, 3); + } + if (unit === 'gram' && value > 999) return formatNumber(value / 1000, 2); + return formatNumber(value, 2); + }; + + const displayUnit = () => { + if (value !== null && unit === 'gram' && value > 999) return 'kg'; + return unit; + }; + + return ( +
+
+
+
+ {isLoading ? ( + + + Memuat... + + ) : ( + <> + {displayValue()}{' '} + {!isNA && {displayUnit()}} + + )} +
+

{title}

+
+
{icon}
+
+
+ {!isNA && trendData.length > 0 ? ( + + + + + [formatNumber(Number(val ?? 0), 2), title]} + labelFormatter={(label) => String(label ?? '')} + contentStyle={{ fontSize: 12, borderRadius: 8 }} + /> + + + ) : ( +
+ {isNA ? 'Data tidak tersedia' : ''} +
+ )} +
+
+ ); +}; + +export default KpiCard; diff --git a/components/PendingCloseQueue.tsx b/components/PendingCloseQueue.tsx new file mode 100644 index 0000000..86c7ff4 --- /dev/null +++ b/components/PendingCloseQueue.tsx @@ -0,0 +1,106 @@ +import React, { useMemo, useState } from 'react'; +import { api, errorMessage } from '../services/apiClient.ts'; +import { useAuth } from '../context/AuthContext.tsx'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner } from './ui/Feedback.tsx'; +import { formatDateId, resolveCycleStatus } from '../utils/format.ts'; + +/** GM queue: approve/reject pending cycle closes from city sites. */ +const PendingCloseQueue: React.FC = () => { + const { user } = useAuth(); + const { cycles, sites, kandangs, reload } = useFarm(); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + const [busyId, setBusyId] = useState(null); + + const isGm = user?.status === 'gm'; + const pending = useMemo( + () => cycles.filter((c) => resolveCycleStatus(c) === 'pending_close'), + [cycles] + ); + + if (pending.length === 0) return null; + + const siteName = (kandangId: number) => { + const kandang = kandangs.find((k) => k.id === kandangId); + const site = sites.find((s) => s.id === kandang?.site); + return site?.site_name ?? '—'; + }; + + const act = async (id: number, decision: 'approve' | 'reject') => { + setBusyId(id); + setError(null); + try { + const result = + decision === 'approve' + ? await api.cycles.approveClose(id) + : await api.cycles.rejectClose(id); + const siteError = + result && typeof result === 'object' && 'site_error' in result + ? (result as { site_error?: string }).site_error + : undefined; + setNotice( + siteError + ? `Keputusan tersimpan di pusat. ${siteError}` + : decision === 'approve' + ? 'Siklus ditutup.' + : 'Permintaan ditolak.' + ); + await reload(); + } catch (err) { + setError(errorMessage(err)); + } finally { + setBusyId(null); + } + }; + + return ( +
+

Permintaan tutup siklus

+

Menunggu persetujuan GM

+ {error && {error}} + {notice && {notice}} +
    + {pending.map((cycle) => ( +
  • +
    +

    + {siteName(cycle.kandang)} · {cycle.kandang_name} +

    +

    + Mulai {formatDateId(cycle.start_date)} + {cycle.proposed_end_date + ? ` · usulan tutup ${formatDateId(cycle.proposed_end_date)}` + : ''} +

    +
    + {isGm ? ( +
    + + +
    + ) : ( + Hanya GM yang dapat menyetujui + )} +
  • + ))} +
+
+ ); +}; + +export default PendingCloseQueue; diff --git a/components/SettingsPage.tsx b/components/SettingsPage.tsx new file mode 100644 index 0000000..615b61b --- /dev/null +++ b/components/SettingsPage.tsx @@ -0,0 +1,557 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { api, errorMessage } from '../services/apiClient.ts'; +import { useAuth } from '../context/AuthContext.tsx'; +import { useFarm } from '../context/FarmContext.tsx'; +import type { CitySite, User, UserStatus } from '../types/api.ts'; +import { Banner, PageHeader, Spinner } from './ui/Feedback.tsx'; + +const inputClass = + 'border border-gray-300 rounded-md px-3 py-2 text-sm w-full focus:ring-red-500 focus:border-red-500'; + +const ROLE_LABELS: Partial> = { + gm: 'GM', + gm_admin: 'GM Admin', + buh: 'BUH', + bu_admin: 'BU Admin', + account_admin: 'Account Admin', +}; + +function slugify(value: string): string { + return value + .trim() + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '') + .slice(0, 64); +} + +function isGmRole(status?: UserStatus | string | null): boolean { + return status === 'gm' || status === 'gm_admin'; +} + +function isBuhRole(status?: UserStatus | string | null): boolean { + return status === 'buh' || status === 'bu_admin'; +} + +const BuhViewList: React.FC = () => { + const { user } = useAuth(); + const isPrimaryBuh = user?.status === 'buh'; + const [gms, setGms] = useState([]); + const [pending, setPending] = useState([]); + const [citySites, setCitySites] = useState([]); + const [loading, setLoading] = useState(true); + const [busyId, setBusyId] = useState(null); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + + const reload = useCallback(async () => { + setLoading(true); + setError(null); + try { + const nextUsers = await api.users.list(); + const nextSites = await api.citySites.list(); + const nextPending = isPrimaryBuh ? await api.users.listPendingManaged() : []; + setGms(nextUsers.filter((u) => u.status === 'gm')); + setPending(nextPending); + setCitySites(nextSites); + } catch (err) { + setError(errorMessage(err)); + } finally { + setLoading(false); + } + }, [isPrimaryBuh]); + + useEffect(() => { + void reload(); + }, [reload]); + + const sitesByGm = useMemo(() => { + const map = new Map(); + for (const site of citySites) { + if (site.registered_by == null) continue; + const rows = map.get(site.registered_by) ?? []; + rows.push(site); + map.set(site.registered_by, rows); + } + return map; + }, [citySites]); + + const decide = async (gmId: number, decision: 'approve' | 'reject') => { + setBusyId(gmId); + setError(null); + try { + if (decision === 'approve') { + await api.users.approveManagedBy(gmId); + setNotice('GM dikonfirmasi di bawah pengelolaan Anda.'); + } else { + await api.users.rejectManagedBy(gmId); + setNotice('Permintaan GM ditolak.'); + } + await reload(); + } catch (err) { + setError(errorMessage(err)); + } finally { + setBusyId(null); + } + }; + + return ( +
+ + {error && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + + {isPrimaryBuh && ( +
+

Permintaan GM

+

+ GM memilih Anda sebagai BUH. Konfirmasi jika mereka memang di bawah pengawasan Anda. +

+ {loading ? ( + + ) : pending.length === 0 ? ( +

Tidak ada permintaan menunggu.

+ ) : ( +
    + {pending.map((gm) => ( +
  • +
    +

    {gm.user_name}

    +

    {ROLE_LABELS[gm.status] ?? gm.status}

    +
    +
    + + +
    +
  • + ))} +
+ )} +
+ )} + +
+

GM yang dikelola

+

+ Sudah dikonfirmasi (akun GM saja). Site di daftar tampilan mereka otomatis masuk rollup + Anda. +

+ {loading ? ( + + ) : gms.length === 0 ? ( +

Belum ada GM yang terkonfirmasi di bawah Anda.

+ ) : ( +
    + {gms.map((gm) => { + const sites = sitesByGm.get(gm.id) ?? []; + return ( +
  • +
    +

    {gm.user_name}

    +

    + {ROLE_LABELS[gm.status] ?? gm.status} · {sites.length} site +

    +
    + {sites.length === 0 ? ( +

    Belum ada site di daftar tampilan GM ini.

    + ) : ( +
      + {sites.map((site) => ( +
    • +

      {site.name}

      +

      + {site.code} + {site.is_active ? '' : ' · nonaktif'} +

      +
    • + ))} +
    + )} +
  • + ); + })} +
+ )} +
+
+ ); +}; + +const GmViewList: React.FC = () => { + const { user, refreshUser } = useAuth(); + const { reload: reloadFarm } = useFarm(); + const [citySites, setCitySites] = useState([]); + const [buhs, setBuhs] = useState([]); + const [selectedBuhId, setSelectedBuhId] = useState(''); + const [loading, setLoading] = useState(true); + const [saving, setSaving] = useState(false); + const [buhBusy, setBuhBusy] = useState(false); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + + const [name, setName] = useState(''); + const [code, setCode] = useState(''); + const [codeTouched, setCodeTouched] = useState(false); + const [apiBaseUrl, setApiBaseUrl] = useState(''); + const [apiKey, setApiKey] = useState(''); + + const flash = (msg: string) => { + setNotice(msg); + setError(null); + }; + + const reload = useCallback(async () => { + setLoading(true); + setError(null); + try { + const sitesPromise = api.citySites.list(); + const mePromise = refreshUser(); + const buhsPromise = + user?.status === 'gm' ? api.users.listBuhs() : Promise.resolve([] as User[]); + const [sites, me, nextBuhs] = await Promise.all([sitesPromise, mePromise, buhsPromise]); + setCitySites(sites); + setBuhs(nextBuhs); + if (me?.managed_by_pending) { + setSelectedBuhId(me.managed_by_pending); + } else if (me?.managed_by) { + setSelectedBuhId(me.managed_by); + } + } catch (err) { + setError(errorMessage(err)); + } finally { + setLoading(false); + } + }, [refreshUser, user?.status]); + + useEffect(() => { + void reload(); + }, [reload]); + + const resetForm = () => { + setName(''); + setCode(''); + setCodeTouched(false); + setApiBaseUrl(''); + setApiKey(''); + }; + + const wrap = async (fn: () => Promise) => { + setSaving(true); + setError(null); + try { + await fn(); + await reload(); + await reloadFarm(); + } catch (err) { + setError(errorMessage(err)); + } finally { + setSaving(false); + } + }; + + const submitBuhRequest = async () => { + if (selectedBuhId === '') return; + setBuhBusy(true); + setError(null); + try { + await api.users.requestManagedBy(selectedBuhId); + await refreshUser(); + flash('Permintaan dikirim. Menunggu konfirmasi BUH.'); + } catch (err) { + setError(errorMessage(err)); + } finally { + setBuhBusy(false); + } + }; + + const cancelBuhRequest = async () => { + setBuhBusy(true); + setError(null); + try { + await api.users.cancelManagedByRequest(); + await refreshUser(); + flash('Permintaan dibatalkan.'); + } catch (err) { + setError(errorMessage(err)); + } finally { + setBuhBusy(false); + } + }; + + return ( +
+ + {error && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + + {user?.status === 'gm' && ( +
+

BUH pengelola

+

+ Pilih BUH yang membawahi Anda. Mereka harus mengonfirmasi sebelum Anda masuk ke rollup + mereka. +

+ {loading ? ( + + ) : ( +
+ {user?.managed_by_name && ( +

+ Saat ini dikonfirmasi di bawah:{' '} + {user.managed_by_name} +

+ )} + {user?.managed_by_pending_name && ( +

+ Menunggu konfirmasi dari {user.managed_by_pending_name} +

+ )} + +
+ + {user?.managed_by_pending != null && ( + + )} +
+
+ )} +
+ )} + +
+
+

Tambah site

+

+ Daftarkan URL API dasbor kota agar data site muncul di daftar tampilan Anda. +

+
{ + e.preventDefault(); + const resolvedCode = code || slugify(name); + if (!resolvedCode) return; + void wrap(async () => { + const created = await api.citySites.create({ + code: resolvedCode, + name: name.trim(), + api_base_url: apiBaseUrl.trim(), + ...(apiKey.trim() ? { api_key: apiKey.trim() } : {}), + is_active: true, + }); + resetForm(); + flash(`Site ${created.name} ditambahkan ke daftar tampilan.`); + }); + }} + > + + + + + +
+
+ +
+

Daftar tampilan

+

+ Site yang terdaftar untuk akun GM / GM Admin Anda. +

+ {loading ? ( + + ) : citySites.length === 0 ? ( +

Belum ada site di daftar tampilan.

+ ) : ( +
    + {citySites.map((site) => ( +
  • +
    +

    {site.name}

    +

    {site.code}

    +

    {site.api_base_url}

    +

    + + {site.is_active ? 'Aktif' : 'Nonaktif'} + + {site.has_api_key ? ' · API key tersimpan' : ''} +

    +
    + +
  • + ))} +
+ )} +
+
+
+ ); +}; + +const SettingsPage: React.FC = () => { + const { user } = useAuth(); + + if (isGmRole(user?.status)) { + return ; + } + + if (isBuhRole(user?.status)) { + return ; + } + + return ( +
+ + + Pengaturan daftar tampilan tersedia untuk GM, GM Admin, BUH, dan BU Admin. + +
+ ); +}; + +export default SettingsPage; diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx new file mode 100644 index 0000000..e28bc5f --- /dev/null +++ b/components/Sidebar.tsx @@ -0,0 +1,151 @@ +import React from 'react'; +import { View } from '../types/common.ts'; +import { useAuth } from '../context/AuthContext.tsx'; +import NavLink, { NavItem } from './sidebar/NavLink.tsx'; + +const navItems: NavItem[] = [ + { + view: 'dashboard', + label: 'Dashboard', + icon: , + }, + { + view: 'dataManagement', + label: 'Hitung Ayam', + icon: , + }, + { + view: 'weightMonitoring', + label: 'Berat Ayam', + icon: , + subItems: [ + { + view: 'weightMonitoring', + label: 'Dashboard Berat', + icon: , + }, + { + view: 'weightStandard', + label: 'Standar Mr. Mike', + icon: , + }, + ], + }, + { + view: 'feedSackCounting', + label: 'Manajemen Pakan', + icon: , + subItems: [ + { + view: 'feedSackCounting', + label: 'Hitung Karung', + icon: , + }, + { + view: 'cobbStandard', + label: 'Standar Performa', + icon: , + }, + ], + }, + { + view: 'iotPanel', + label: 'Panel IoT', + icon: , + }, + { + view: 'fcrDashboard', + label: 'FCR', + icon: , + }, + { + view: 'eefDashboard', + label: 'EEF', + icon: , + }, + { + view: 'kandangRanking', + label: 'Peringkat Kandang', + icon: , + }, + { + view: 'kandangSettings', + label: 'Pengaturan', + icon: , + }, + { + view: 'userManagement', + label: 'Manajemen Akun', + icon: , + }, +]; + +interface SidebarProps { + isCollapsed: boolean; + view: View; + setView: (view: View) => void; + onToggleCollapse: () => void; +} + +const Sidebar: React.FC = ({ isCollapsed, view, setView, onToggleCollapse }) => { + const { user } = useAuth(); + const canOpenSettings = + user?.status === 'gm' || + user?.status === 'gm_admin' || + user?.status === 'buh' || + user?.status === 'bu_admin'; + const canOpenUserManagement = + user?.status === 'superuser' || Boolean(user?.is_superuser); + const visibleNav = navItems.filter((item) => { + if (item.view === 'kandangSettings') return canOpenSettings; + if (item.view === 'userManagement') return canOpenUserManagement; + return true; + }); + + return ( + + ); +}; + +export default Sidebar; diff --git a/components/UserManagementPage.tsx b/components/UserManagementPage.tsx new file mode 100644 index 0000000..4c9ac1a --- /dev/null +++ b/components/UserManagementPage.tsx @@ -0,0 +1,362 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { api, errorMessage } from '../services/apiClient.ts'; +import { useAuth } from '../context/AuthContext.tsx'; +import type { User, UserStatus } from '../types/api.ts'; +import { Banner, PageHeader, Spinner } from './ui/Feedback.tsx'; + +const inputClass = + 'border border-gray-300 rounded-md px-3 py-2 text-sm w-full focus:ring-red-500 focus:border-red-500'; + +const ROLE_LABELS: Record = { + inactive: 'Inactive', + gm: 'GM', + gm_admin: 'GM Admin', + buh: 'BUH', + bu_admin: 'BU Admin', + director: 'Director', + director_admin: 'Director Admin', + account_admin: 'Account Admin', + superuser: 'Superuser', +}; + +const ASSIGNABLE_STATUSES: UserStatus[] = [ + 'gm', + 'gm_admin', + 'buh', + 'bu_admin', + 'director', + 'director_admin', + 'account_admin', + 'inactive', +]; + +const UserManagementPage: React.FC = () => { + const { user: currentUser } = useAuth(); + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(true); + const [saving, setSaving] = useState(false); + const [busyId, setBusyId] = useState(null); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + + const [userName, setUserName] = useState(''); + const [status, setStatus] = useState('gm'); + const [password, setPassword] = useState(''); + + const [editId, setEditId] = useState(null); + const [editStatus, setEditStatus] = useState('gm'); + const [resetId, setResetId] = useState(null); + const [resetPassword, setResetPassword] = useState(''); + + const reload = useCallback(async () => { + setLoading(true); + setError(null); + try { + setUsers(await api.users.list()); + } catch (err) { + setError(errorMessage(err)); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + void reload(); + }, [reload]); + + const wrap = async (fn: () => Promise) => { + setError(null); + setNotice(null); + try { + await fn(); + } catch (err) { + setError(errorMessage(err)); + } + }; + + const onCreate = (e: React.FormEvent) => { + e.preventDefault(); + void wrap(async () => { + setSaving(true); + try { + await api.users.create({ + user_name: userName.trim(), + status, + password, + }); + setNotice( + `Akun "${userName.trim()}" dibuat. Bagikan password sementara secara aman (di luar sistem).` + ); + setUserName(''); + setPassword(''); + setStatus('gm'); + await reload(); + } finally { + setSaving(false); + } + }); + }; + + const onSaveStatus = (id: number) => { + void wrap(async () => { + setBusyId(id); + try { + await api.users.update(id, { status: editStatus }); + setNotice('Status pengguna diperbarui.'); + setEditId(null); + await reload(); + } finally { + setBusyId(null); + } + }); + }; + + const onDeactivate = (user: User) => { + if (!window.confirm(`Nonaktifkan akun "${user.user_name}"?`)) return; + void wrap(async () => { + setBusyId(user.id); + try { + await api.users.update(user.id, { status: 'inactive' }); + setNotice(`Akun "${user.user_name}" dinonaktifkan.`); + await reload(); + } finally { + setBusyId(null); + } + }); + }; + + const onResetPassword = (id: number) => { + void wrap(async () => { + setBusyId(id); + try { + await api.users.setPassword(id, resetPassword); + setNotice('Password direset. Bagikan password baru secara aman (di luar sistem).'); + setResetId(null); + setResetPassword(''); + await reload(); + } finally { + setBusyId(null); + } + }); + }; + + return ( +
+ + {error && {error}} + {notice && {notice}} + +
+

Buat pengguna baru

+
+ + + +
+ +
+
+

+ Password tidak dikirim lewat email. Bagikan secara terpisah ke pengguna. +

+
+ +
+

Daftar pengguna

+ {loading ? ( +
+ +
+ ) : ( +
+ + + + + + + + + + + {users.map((user) => { + const isSelf = currentUser?.id === user.id; + return ( + + + + + + + ); + })} + +
UsernameRoleManaged byAksi
+ {user.user_name} + {isSelf ? ( + (Anda) + ) : null} + + {!isSelf && editId === user.id ? ( + + ) : ( + ROLE_LABELS[user.status] ?? user.status + )} + + {user.managed_by_name ?? '—'} + +
+ {!isSelf && editId === user.id ? ( + <> + + + + ) : null} + {!isSelf && editId !== user.id ? ( + + ) : null} + {!isSelf && user.status !== 'inactive' ? ( + + ) : null} + {isSelf ? ( + + Role & status akun sendiri tidak bisa diubah di sini. + + ) : null} + {resetId === user.id ? ( +
+ setResetPassword(e.target.value)} + autoComplete="new-password" + /> + + +
+ ) : ( + + )} +
+
+ {users.length === 0 && ( +

Belum ada pengguna.

+ )} +
+ )} +
+
+ ); +}; + +export default UserManagementPage; diff --git a/components/WeightMonitoringPage.tsx b/components/WeightMonitoringPage.tsx new file mode 100644 index 0000000..0ac0a72 --- /dev/null +++ b/components/WeightMonitoringPage.tsx @@ -0,0 +1,313 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { api, ApiError, errorMessage } from '../services/apiClient.ts'; +import type { AIInsight, ChickenWeight, LatestAvg } from '../types/api.ts'; +import { useFarm } from '../context/FarmContext.tsx'; +import { Banner, EmptyFarm, Spinner } from './ui/Feedback.tsx'; +import { formatDateId, formatNumber } from '../utils/format.ts'; +import { formatWeight } from '../utils/weight.ts'; +import WeightStats from './weight/WeightStats.tsx'; +import DailyWeightProgressionChart from './weight/DailyWeightProgressionChart.tsx'; +import DailyWeightGainChart from './weight/DailyWeightGainChart.tsx'; +import DailyDetailPanel from './weight/DailyDetailPanel.tsx'; + +const WeightMonitoringPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle } = useFarm(); + const [rows, setRows] = useState([]); + const [latest, setLatest] = useState(null); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [refreshing, setRefreshing] = useState(false); + const [error, setError] = useState(null); + const [selectedDate, setSelectedDate] = useState(''); + + const reload = async (cycleId: number) => { + setError(null); + try { + const [list, insightRows] = await Promise.all([ + api.weights.list({ cycle_id: cycleId }), + api.insights.list({ cycle_id: cycleId }), + ]); + setRows(list); + setInsights(insightRows); + try { + setLatest(await api.weights.latestAvg({ cycle_id: cycleId })); + } catch (err) { + if (err instanceof ApiError && err.status === 404) setLatest(null); + else throw err; + } + } catch (err) { + setError(errorMessage(err)); + } + }; + + useEffect(() => { + if (!selectedCycle) { + setRows([]); + setLatest(null); + setInsights([]); + setSelectedDate(''); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + setRefreshing(false); + try { + await reload(selectedCycle.id); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedCycle]); + + // Days without a weighing are stored as 0 g. Charts skip those days so the + // line does not drop to zero at the end of a cycle, mirroring the old + // dashboard which only plotted days with actual timbangan data. + const chartRows = useMemo(() => rows.filter((row) => row.average_weight > 0), [rows]); + + // Default the date picker to the newest row with a real weighing once data + // loads, so the detail panel opens with meaningful values. + useEffect(() => { + if (!selectedDate) { + const newestMeaningful = chartRows[0] ?? rows[0]; + if (newestMeaningful) setSelectedDate(newestMeaningful.date); + } + }, [rows, chartRows, selectedDate]); + + const handleRefresh = async () => { + if (!selectedCycle) return; + setRefreshing(true); + try { + await reload(selectedCycle.id); + } catch { + // error state is set inside reload + } finally { + setRefreshing(false); + } + }; + + const docWeight = selectedCycle?.chick_in_weight ?? 35; + + const selectedRow = useMemo( + () => rows.find((row) => row.date === selectedDate) ?? null, + [rows, selectedDate] + ); + + const minDate = rows.length > 0 ? (rows[rows.length - 1]?.date ?? '') : ''; + const maxDate = rows.length > 0 ? (rows[0]?.date ?? '') : ''; + + const weightInsights = useMemo(() => { + const matched = insights.filter((item) => { + const section = `${item.section ?? ''} ${item.alert ?? ''}`.toLowerCase(); + return section.includes('berat') || section.includes('weight') || section.includes('timbang'); + }); + return (matched.length > 0 ? matched : insights).slice(0, 4); + }, [insights]); + + // Prefer the latest non-zero row for the KPI card so a closed cycle with + // trailing empty days does not read as "0 g". + const kpiLatest = useMemo(() => { + if (!latest) return null; + if (latest.average_weight > 0) return latest; + const fallback = rows.find((row) => row.average_weight > 0); + if (!fallback) return null; + return { + average_weight: fallback.average_weight, + date: fallback.date, + age: fallback.age, + uniformity: fallback.uniformity, + average_daily_gain: fallback.average_daily_gain, + cycle: fallback.cycle, + kandang: fallback.kandang, + }; + }, [latest, rows]); + + if (!selectedCycle) return ; + + return ( +
+ {/* Header */} +
+
+
+ +
+
+

Dashboard Berat Ayam

+

+ Analisis pertumbuhan dan kesejahteraan bobot ayam secara real-time. +

+ {!loading && latest?.date && ( +

+ + Terakhir diperbarui: {formatDateId(latest.date)} +

+ )} +
+
+ +
+ + {error && ( +
+ {error} +
+ )} + + {loading && rows.length === 0 ? ( + + ) : ( +
+ {/* AI Insight */} +
+

AI Insight

+ {weightInsights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {weightInsights.map((item) => ( +
+
+
+

+ {item.section} +

+

+ {item.alert || 'Insight'} +

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + {/* TOP SECTION: DATA SELURUH SIKLUS */} +
+
+
+ +
+
+ +
+
+ +
+ + {/* ===== SEPARATOR: DATA PER HARI ===== */} +
+
+
+

Data Per Hari

+

+ Pilih tanggal untuk melihat detail data harian +

+
+
+ +
+ + setSelectedDate(e.target.value)} + className="px-2 py-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-red-500 focus:border-red-500" + /> +
+
+
+ + + + {/* Riwayat lengkap */} +
+

Riwayat Berat Harian

+
+ + + + {['Tanggal', 'Umur', 'DOC', 'AVG', 'Uniformity', 'ADG'].map((h) => ( + + ))} + + + + {rows.length === 0 ? ( + + + + ) : ( + rows.map((row) => ( + + + + + + + + + )) + )} + +
+ {h} +
+ Belum ada data berat untuk siklus ini. +
{formatDateId(row.date)}{row.age} + {formatWeight(row.doc_weight, { decimals: 0 })} + + {formatWeight(row.average_weight, { stripTrailingZeros: true })} + {formatNumber(row.uniformity, 2, 2, true)}% + {formatNumber(row.average_daily_gain, 2, 2, true)} +
+
+
+
+ + {/* Info Box */} +
+
+ +
+

Informasi Pembaruan Data

+
    +
  • • Klik tombol "Refresh" untuk memperbarui data secara manual
  • +
  • • Grafik menampilkan data dari awal siklus hingga hari ini
  • +
  • • Target berat menggunakan standar performa Ross 308
  • +
+
+
+
+
+ )} +
+ ); +}; + +export default WeightMonitoringPage; diff --git a/components/WeightStandardPage.tsx b/components/WeightStandardPage.tsx new file mode 100644 index 0000000..25df951 --- /dev/null +++ b/components/WeightStandardPage.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { weightStandardData } from '../mockData/weightStandardData.ts'; + +const WeightStandardPage: React.FC = () => { + const { headers, data } = weightStandardData; + + return ( +
+
+ +
+

Tabel Standar Bobot Ross 308

+

+ Driven from pen trial data - so difference may be more +

+
+
+ +
+
+ + + + + {headers.map((header) => ( + + ))} + + + + {data.map((row, rowIndex) => ( + + + {row.values.map((value, colIndex) => { + const isRedText = (colIndex + 1) % 7 === 0; + return ( + + ); + })} + + ))} + +
+ DO/wt + + {header} +
+ {row.day} + + {value} +
+
+
+
AVIAGEN PROPRIETARY
+
+ ); +}; + +export default WeightStandardPage; diff --git a/components/__tests__/AccountAdminShell.test.tsx b/components/__tests__/AccountAdminShell.test.tsx new file mode 100644 index 0000000..d0a4938 --- /dev/null +++ b/components/__tests__/AccountAdminShell.test.tsx @@ -0,0 +1,32 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import AccountAdminShell from '../AccountAdminShell.tsx'; + +vi.mock('../../context/AuthContext.tsx', () => ({ + useAuth: () => ({ + user: { + id: 9, + user_name: 'account_admin', + status: 'account_admin', + is_superuser: false, + created_at: '', + updated_at: '', + }, + logout: vi.fn(), + }), +})); + +vi.mock('../UserManagementPage.tsx', () => ({ + default: () =>
User management content
, +})); + +describe('AccountAdminShell', () => { + it('shows only User Management nav, not ops dashboards', () => { + render(); + expect(screen.getByText('Manajemen Akun')).toBeInTheDocument(); + expect(screen.getByText('User management content')).toBeInTheDocument(); + expect(screen.queryByText('Dashboard')).not.toBeInTheDocument(); + expect(screen.queryByText('Hitung Ayam')).not.toBeInTheDocument(); + expect(screen.queryByText('FCR')).not.toBeInTheDocument(); + }); +}); diff --git a/components/__tests__/FeedSackCountingPage.test.tsx b/components/__tests__/FeedSackCountingPage.test.tsx new file mode 100644 index 0000000..cb30af8 --- /dev/null +++ b/components/__tests__/FeedSackCountingPage.test.tsx @@ -0,0 +1,288 @@ +import { render, screen } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { api } from '../../services/apiClient.ts'; +import FeedSackCountingPage from '../FeedSackCountingPage.tsx'; + +const { karungRows, manualRows, cycle, mismatchedKarungRows, mismatchedManualRows } = vi.hoisted( + () => { + const cycle = { + id: 1, + kandang: 1, + flock: 1, + total_days: 35, + current_day: 2, + start_date: '2026-08-10', + end_date: '2026-09-13', + chick_in_weight: 45, + doc_in_count: 20000, + status: 'gm', + feed_initial_balance: 0, + created_at: '', + updated_at: '', + }; + const karungRows = [ + { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-10', + in_today: 10, + out_today: 4, + in_total: 10, + out_total: 4, + feed_use_today: 4, + feed_use_total: 4, + created_at: '', + updated_at: '', + }, + { + id: 2, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-11', + in_today: 12, + out_today: 6, + in_total: 22, + out_total: 10, + feed_use_today: 6, + feed_use_total: 10, + created_at: '', + updated_at: '', + }, + ]; + const manualRows = [ + { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-10', + age_manual: 0, + mortality_manual: 0, + mortality_manual_total: 0, + feed_in_manual: 10, + feed_use_manual: 4, + feed_in_manual_total: 10, + feed_use_manual_total: 4, + feed_out_manual: 0, + feed_out_manual_total: 0, + harvest_manual: 0, + harvest_manual_total: 0, + harvest_weight_manual: 0, + harvest_weight_manual_total: 0, + manual_weight: 0, + average_harvest_day_manual: 0, + average_harvest_weight_manual: 0, + fcr_manual: 0, + eef_manual: 0, + created_at: '', + updated_at: '', + }, + { + id: 2, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-11', + age_manual: 1, + mortality_manual: 0, + mortality_manual_total: 0, + feed_in_manual: 10, + feed_use_manual: 7, + feed_in_manual_total: 20, + feed_use_manual_total: 11, + feed_out_manual: 0, + feed_out_manual_total: 0, + harvest_manual: 0, + harvest_manual_total: 0, + harvest_weight_manual: 0, + harvest_weight_manual_total: 0, + manual_weight: 0, + average_harvest_day_manual: 0, + average_harvest_weight_manual: 0, + fcr_manual: 0, + eef_manual: 0, + created_at: '', + updated_at: '', + }, + ]; + // IoT already on the newer day; manual only exists for the previous day. + const mismatchedKarungRows = [ + { + id: 10, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-09-02', + in_today: 192, + out_today: 1, + in_total: 192, + out_total: 1, + feed_use_today: 7, + feed_use_total: 7, + created_at: '', + updated_at: '', + }, + { + id: 11, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-09-03', + in_today: 50, + out_today: 0, + in_total: 242, + out_total: 1, + feed_use_today: 4, + feed_use_total: 11, + created_at: '', + updated_at: '', + }, + ]; + const mismatchedManualRows = [ + { + id: 10, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-09-02', + age_manual: 0, + mortality_manual: 0, + mortality_manual_total: 0, + feed_in_manual: 192, + feed_use_manual: 7, + feed_in_manual_total: 192, + feed_use_manual_total: 7, + feed_out_manual: 1, + feed_out_manual_total: 1, + harvest_manual: 0, + harvest_manual_total: 0, + harvest_weight_manual: 0, + harvest_weight_manual_total: 0, + manual_weight: 0, + average_harvest_day_manual: 0, + average_harvest_weight_manual: 0, + fcr_manual: 0, + eef_manual: 0, + created_at: '', + updated_at: '', + }, + ]; + return { karungRows, manualRows, cycle, mismatchedKarungRows, mismatchedManualRows }; +}); + +vi.mock('../../services/apiClient.ts', () => ({ + api: { + karungs: { + list: vi.fn().mockResolvedValue(karungRows), + request: vi.fn().mockResolvedValue({ karung: {}, upstream: {} }), + }, + insights: { + list: vi.fn().mockResolvedValue([]), + }, + manualInputs: { + list: vi.fn().mockResolvedValue(manualRows), + }, + }, + errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), +})); + +vi.mock('../../context/FarmContext.tsx', () => ({ + useFarm: () => ({ + selectedSite: { id: 1, site_name: 'Sukawarna', user: 1, created_at: '', updated_at: '' }, + selectedKandang: { + id: 1, + kandang_name: 'Kandang 1', + site: 1, + created_at: '', + updated_at: '', + }, + selectedCycle: cycle, + cycles: [cycle], + setSelectedCycleId: vi.fn(), + updateCycle: vi.fn(), + }), +})); + +class ResizeObserverStub { + observe() {} + unobserve() {} + disconnect() {} +} + +describe('FeedSackCountingPage', () => { + beforeEach(() => { + vi.mocked(api.karungs.list).mockResolvedValue(karungRows); + vi.mocked(api.manualInputs.list).mockResolvedValue(manualRows); + vi.mocked(api.insights.list).mockResolvedValue([]); + }); + + it('renders the recreated hitung karung view with stats, saldo, and daily table', async () => { + vi.stubGlobal('ResizeObserver', ResizeObserverStub); + try { + render( undefined} />); + + expect(await screen.findByRole('heading', { name: 'Hitung Karung' })).toBeInTheDocument(); + expect( + screen.getByText('Monitoring karung masuk dan karung dituang per hari') + ).toBeInTheDocument(); + expect(screen.getByText(/10 Agu 2026 - 13 Sep 2026/i)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Sync hari ini/i })).toBeInTheDocument(); + + // Ringkasan stats + expect(screen.getAllByText('Karung Masuk').length).toBeGreaterThan(0); + expect(screen.getAllByText('Karung Dituang').length).toBeGreaterThan(0); + expect(screen.getAllByText('Karung Keluar').length).toBeGreaterThan(0); + expect(screen.getAllByText('12').length).toBeGreaterThan(0); // in_today dari snapshot terbaru + + // Saldo card + expect(screen.getByRole('heading', { name: 'Saldo Karung IOT' })).toBeInTheDocument(); + + // Trend chart + expect(screen.getByRole('heading', { name: 'Tren Harian Karung IOT' })).toBeInTheDocument(); + + // Daily table (separate masuk & tuang boxes, each with Manual/IOT/Akurasi) + expect( + screen.getByRole('heading', { name: 'Rincian Harian Karung IOT' }) + ).toBeInTheDocument(); + expect(screen.getAllByText('KARUNG MASUK').length).toBeGreaterThan(0); + expect(screen.getAllByText('KARUNG TUANG').length).toBeGreaterThan(0); + // Headers appear in both boxes + expect(screen.getAllByText('Manual').length).toBeGreaterThanOrEqual(2); + expect(screen.getAllByText('IOT').length).toBeGreaterThanOrEqual(2); + expect(screen.getAllByText('Akurasi').length).toBeGreaterThanOrEqual(2); + // Total columns still show snapshot totals + expect(screen.getAllByText('22').length).toBeGreaterThan(0); + expect(screen.getAllByText('10').length).toBeGreaterThan(0); + // Accuracy: hari ke-2 masuk manual 10 vs IOT 12 -> 83.3% + expect(screen.getAllByText('83.3%').length).toBeGreaterThan(0); + // Hari ke-1 matching values -> 100.0% + expect(screen.getAllByText('100.0%').length).toBeGreaterThan(0); + } finally { + vi.unstubAllGlobals(); + } + }); + + it('does not reuse yesterday manual values on the latest IoT day stats cards', async () => { + vi.stubGlobal('ResizeObserver', ResizeObserverStub); + vi.mocked(api.karungs.list).mockResolvedValue(mismatchedKarungRows); + vi.mocked(api.manualInputs.list).mockResolvedValue(mismatchedManualRows); + try { + render( undefined} />); + + expect(await screen.findByRole('heading', { name: 'Hitung Karung' })).toBeInTheDocument(); + // Latest IoT day still shows. + expect(screen.getAllByText('50').length).toBeGreaterThan(0); + // Summary Manual cards show 0 when the latest IoT day has no matching manual row. + expect(screen.getAllByText('0').length).toBeGreaterThanOrEqual(6); + // Daily table still keeps the real 2 Sep manual row across masuk/tuang/keluar boxes. + expect(screen.getAllByText('192').length).toBeGreaterThan(0); + expect(screen.getAllByText('3 Sep 2026').length).toBeGreaterThan(0); + expect(screen.getAllByText('2 Sep 2026').length).toBeGreaterThan(0); + } finally { + vi.unstubAllGlobals(); + } + }); +}); diff --git a/components/__tests__/SettingsPage.test.tsx b/components/__tests__/SettingsPage.test.tsx new file mode 100644 index 0000000..fe183b0 --- /dev/null +++ b/components/__tests__/SettingsPage.test.tsx @@ -0,0 +1,216 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import SettingsPage from '../SettingsPage.tsx'; + +const { + listMock, + createMock, + removeMock, + usersListMock, + buhsMock, + pendingMock, + requestMock, + approveMock, + refreshUserMock, + authState, +} = vi.hoisted(() => ({ + listMock: vi.fn(), + createMock: vi.fn(), + removeMock: vi.fn(), + usersListMock: vi.fn(), + buhsMock: vi.fn(), + pendingMock: vi.fn(), + requestMock: vi.fn(), + approveMock: vi.fn(), + refreshUserMock: vi.fn(), + authState: { + user: { + id: 5, + user_name: 'gm.user', + status: 'gm' as string, + managed_by: null as number | null, + managed_by_name: null as string | null, + managed_by_pending: null as number | null, + managed_by_pending_name: null as string | null, + created_at: '', + updated_at: '', + }, + }, +})); + +vi.mock('../../services/apiClient.ts', () => ({ + api: { + citySites: { + list: listMock, + create: createMock, + remove: removeMock, + }, + users: { + list: usersListMock, + listBuhs: buhsMock, + listPendingManaged: pendingMock, + requestManagedBy: requestMock, + cancelManagedByRequest: vi.fn(), + approveManagedBy: approveMock, + rejectManagedBy: vi.fn(), + }, + }, + errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), +})); + +vi.mock('../../context/AuthContext.tsx', () => ({ + useAuth: () => ({ + user: authState.user, + refreshUser: refreshUserMock, + }), +})); + +vi.mock('../../context/FarmContext.tsx', () => ({ + useFarm: () => ({ + reload: vi.fn().mockResolvedValue(undefined), + }), +})); + +describe('SettingsPage city site registry', () => { + beforeEach(() => { + listMock.mockReset(); + createMock.mockReset(); + removeMock.mockReset(); + usersListMock.mockReset(); + buhsMock.mockReset(); + pendingMock.mockReset(); + requestMock.mockReset(); + approveMock.mockReset(); + refreshUserMock.mockReset(); + authState.user = { + id: 5, + user_name: 'gm.user', + status: 'gm', + managed_by: null, + managed_by_name: null, + managed_by_pending: null, + managed_by_pending_name: null, + created_at: '', + updated_at: '', + }; + refreshUserMock.mockResolvedValue(authState.user); + listMock.mockResolvedValue([ + { + id: 1, + code: 'sukawarna', + name: 'Sukawarna', + api_base_url: 'https://sukawarna.example/api/v1', + has_api_key: true, + registered_by: 5, + registered_by_name: 'gm.user', + is_active: true, + last_synced_at: null, + last_sync_status: '', + last_sync_message: '', + created_at: '', + updated_at: '', + }, + ]); + createMock.mockResolvedValue({ + id: 2, + code: 'cikupa', + name: 'Cikupa', + api_base_url: 'https://cikupa.example/api/v1', + has_api_key: false, + registered_by: 5, + registered_by_name: 'gm.user', + is_active: true, + last_synced_at: null, + last_sync_status: '', + last_sync_message: '', + created_at: '', + updated_at: '', + }); + buhsMock.mockResolvedValue([ + { id: 2, user_name: 'buh', status: 'buh', created_at: '', updated_at: '' }, + ]); + usersListMock.mockResolvedValue([ + { + id: 5, + user_name: 'gm', + status: 'gm', + managed_by: 2, + created_at: '', + updated_at: '', + }, + ]); + pendingMock.mockResolvedValue([]); + }); + + it('lists registered city sites for GM', async () => { + render(); + + expect(await screen.findByText('Sukawarna')).toBeInTheDocument(); + expect(screen.getByText('BUH pengelola')).toBeInTheDocument(); + }); + + it('submits a new city site to the view list', async () => { + render(); + await screen.findByText('Sukawarna'); + + fireEvent.change(screen.getByPlaceholderText('Contoh: Sukawarna'), { + target: { value: 'Cikupa' }, + }); + fireEvent.change(screen.getByPlaceholderText('https://site.example/api/v1'), { + target: { value: 'https://cikupa.example/api/v1' }, + }); + fireEvent.click(screen.getByRole('button', { name: 'Tambah ke daftar' })); + + await waitFor(() => expect(createMock).toHaveBeenCalledTimes(1)); + expect(createMock).toHaveBeenCalledWith({ + code: 'cikupa', + name: 'Cikupa', + api_base_url: 'https://cikupa.example/api/v1', + is_active: true, + }); + }); + + it('lets GM request a BUH', async () => { + requestMock.mockResolvedValue({ + ...authState.user, + managed_by_pending: 2, + managed_by_pending_name: 'buh', + }); + render(); + await screen.findByText('BUH pengelola'); + + fireEvent.change(screen.getByLabelText(/Pilih BUH/i), { target: { value: '2' } }); + fireEvent.click(screen.getByRole('button', { name: 'Kirim permintaan' })); + + await waitFor(() => expect(requestMock).toHaveBeenCalledWith(2)); + }); + + it('shows pending GM confirmation for BUH', async () => { + authState.user = { + id: 2, + user_name: 'buh', + status: 'buh', + managed_by: null, + managed_by_name: null, + managed_by_pending: null, + managed_by_pending_name: null, + created_at: '', + updated_at: '', + }; + pendingMock.mockResolvedValue([ + { + id: 5, + user_name: 'gm.user', + status: 'gm', + created_at: '', + updated_at: '', + }, + ]); + + render(); + + expect(await screen.findByText('Permintaan GM')).toBeInTheDocument(); + expect(screen.getByText('gm.user')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Konfirmasi' })).toBeInTheDocument(); + }); +}); diff --git a/components/__tests__/UserManagementPage.test.tsx b/components/__tests__/UserManagementPage.test.tsx new file mode 100644 index 0000000..9d83a58 --- /dev/null +++ b/components/__tests__/UserManagementPage.test.tsx @@ -0,0 +1,141 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import UserManagementPage from '../UserManagementPage.tsx'; + +const { listMock, createMock, updateMock, setPasswordMock, authState } = vi.hoisted(() => ({ + listMock: vi.fn(), + createMock: vi.fn(), + updateMock: vi.fn(), + setPasswordMock: vi.fn(), + authState: { + user: { + id: 99, + user_name: 'account_admin', + status: 'account_admin' as string, + created_at: '', + updated_at: '', + }, + }, +})); + +vi.mock('../../services/apiClient.ts', () => ({ + api: { + users: { + list: listMock, + create: createMock, + update: updateMock, + setPassword: setPasswordMock, + }, + }, + errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), +})); + +vi.mock('../../context/AuthContext.tsx', () => ({ + useAuth: () => ({ + user: authState.user, + }), +})); + +describe('UserManagementPage', () => { + beforeEach(() => { + listMock.mockReset(); + createMock.mockReset(); + updateMock.mockReset(); + setPasswordMock.mockReset(); + authState.user = { + id: 99, + user_name: 'account_admin', + status: 'account_admin', + created_at: '', + updated_at: '', + }; + listMock.mockResolvedValue([ + { + id: 1, + user_name: 'gm1', + status: 'gm', + managed_by_name: 'buh1', + created_at: '', + updated_at: '', + }, + { + id: 99, + user_name: 'account_admin', + status: 'account_admin', + managed_by_name: null, + created_at: '', + updated_at: '', + }, + ]); + createMock.mockResolvedValue({ + id: 2, + user_name: 'newgm', + status: 'gm', + created_at: '', + updated_at: '', + }); + updateMock.mockResolvedValue({}); + setPasswordMock.mockResolvedValue({}); + vi.spyOn(window, 'confirm').mockReturnValue(true); + }); + + it('renders list from api.users.list', async () => { + render(); + expect(await screen.findByText('gm1')).toBeInTheDocument(); + expect(screen.getByText('buh1')).toBeInTheDocument(); + expect(screen.getAllByText('GM').length).toBeGreaterThan(0); + }); + + it('submits create with password', async () => { + render(); + await screen.findByText('gm1'); + + fireEvent.change(screen.getByLabelText(/Username/i), { + target: { value: 'newgm' }, + }); + fireEvent.change(screen.getByLabelText(/Password sementara/i), { + target: { value: 'temp123' }, + }); + fireEvent.click(screen.getByRole('button', { name: /Buat akun/i })); + + await waitFor(() => { + expect(createMock).toHaveBeenCalledWith({ + user_name: 'newgm', + status: 'gm', + password: 'temp123', + }); + }); + }); + + it('deactivates user', async () => { + render(); + await screen.findByText('gm1'); + fireEvent.click(screen.getByRole('button', { name: /Nonaktifkan/i })); + await waitFor(() => { + expect(updateMock).toHaveBeenCalledWith(1, { status: 'inactive' }); + }); + }); + + it('hides deactivate and role change on own row', async () => { + render(); + expect(await screen.findByText('(Anda)')).toBeInTheDocument(); + expect(screen.getAllByRole('button', { name: /Nonaktifkan/i })).toHaveLength(1); + expect(screen.getAllByRole('button', { name: /Ubah role/i })).toHaveLength(1); + expect( + screen.getByText(/Role & status akun sendiri tidak bisa diubah/i) + ).toBeInTheDocument(); + }); + + it('resets password', async () => { + render(); + await screen.findByText('gm1'); + fireEvent.click(screen.getAllByRole('button', { name: /Reset password/i })[0]); + fireEvent.change(screen.getByPlaceholderText(/Password baru/i), { + target: { value: 'reset-me' }, + }); + fireEvent.click(screen.getByRole('button', { name: /^Reset$/i })); + await waitFor(() => { + expect(setPasswordMock).toHaveBeenCalledWith(1, 'reset-me'); + }); + }); +}); diff --git a/components/auth/AuthPage.tsx b/components/auth/AuthPage.tsx new file mode 100644 index 0000000..55f3da9 --- /dev/null +++ b/components/auth/AuthPage.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import LoginForm from './LoginForm.tsx'; + +const AuthPage: React.FC = () => ( +
+
+
+ Charoen Pokphand Logo +

Solusi AI Peternakan Ayam

+
+
+ +
+
+
+); + +export default AuthPage; diff --git a/components/auth/LoginForm.tsx b/components/auth/LoginForm.tsx new file mode 100644 index 0000000..51532d3 --- /dev/null +++ b/components/auth/LoginForm.tsx @@ -0,0 +1,78 @@ +import React, { useState } from 'react'; +import { useAuth } from '../../context/AuthContext.tsx'; +import { errorMessage } from '../../services/apiClient.ts'; + +const LoginForm: React.FC = () => { + const { login } = useAuth(); + const [userName, setUserName] = useState(''); + const [password, setPassword] = useState(''); + const [error, setError] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(''); + setIsLoading(true); + try { + await login(userName, password); + } catch (err) { + setError(errorMessage(err)); + } finally { + setIsLoading(false); + } + }; + + return ( +
void handleSubmit(e)} className="space-y-6"> + {error && ( +
+ {error} +
+ )} +
+ +
+ setUserName(e.target.value)} + className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm" + placeholder="Nama pengguna" + /> +
+
+
+ +
+ setPassword(e.target.value)} + className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-red-500 focus:border-red-500 sm:text-sm" + /> +
+
+ +
+ ); +}; + +export default LoginForm; diff --git a/components/common/ErrorBoundary.tsx b/components/common/ErrorBoundary.tsx new file mode 100644 index 0000000..14ee593 --- /dev/null +++ b/components/common/ErrorBoundary.tsx @@ -0,0 +1,55 @@ +import { Component, ErrorInfo, ReactNode } from 'react'; + +interface Props { + children: ReactNode; + fallback?: ReactNode; +} + +interface State { + hasError: boolean; + error: Error | null; +} + +class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('ErrorBoundary caught error:', error, errorInfo); + // TODO: Send to error tracking service (Sentry, LogRocket, etc.) + } + + render() { + if (this.state.hasError) { + return ( + this.props.fallback || ( +
+
+ +

Something went wrong

+

+ We're sorry, but something unexpected happened. Please refresh the page. +

+ +
+
+ ) + ); + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/components/counting/CountingAccuracyWarningBanner.tsx b/components/counting/CountingAccuracyWarningBanner.tsx new file mode 100644 index 0000000..5255136 --- /dev/null +++ b/components/counting/CountingAccuracyWarningBanner.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import type { CountingAccuracyWarning } from '../../utils/countingAccuracyWarning.ts'; +import { formatNumber } from '../../utils/format.ts'; + +type Props = { + warning: CountingAccuracyWarning; +}; + +const CountingAccuracyWarningBanner: React.FC = ({ warning }) => { + const isOver = warning.direction === 'over'; + const title = isOver + ? 'Hitung ayam IoT lebih tinggi dari stock manual' + : 'Akurasi hitung ayam IoT rendah (IoT lebih rendah dari stock)'; + const body = isOver + ? 'Manager perlu cek: kemungkinan fraud / ayam baru yang belum tercatat, atau AI overcount; pastikan juga video kamera lengkap dan tidak bermasalah.' + : 'Manager perlu cek: video kamera lengkap atau tidak, kemungkinan masalah AI, atau ada selisih stok.'; + + return ( +
+
+ +
+

{title}

+

+ Hari {warning.day} · IoT {formatNumber(warning.iotCount, 0)} vs stock{' '} + {formatNumber(warning.stockAkhir, 0)} (akurasi {formatNumber(warning.accuracy, 1)}%) +

+

{body}

+
+
+
+ ); +}; + +export default CountingAccuracyWarningBanner; diff --git a/components/counting/DataManagementPage.tsx b/components/counting/DataManagementPage.tsx new file mode 100644 index 0000000..789dbc4 --- /dev/null +++ b/components/counting/DataManagementPage.tsx @@ -0,0 +1,850 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { api, errorMessage } from '../../services/apiClient.ts'; +import type { AIInsight, ChickenCounting, KPI, ManualInput } from '../../types/api.ts'; +import { useFarm } from '../../context/FarmContext.tsx'; +import { Banner, EmptyFarm, PageHeader, Spinner } from '../ui/Feedback.tsx'; +import { + addDaysIso, + cycleDayForDate, + formatDateId, + formatDateRange, + formatNumber, + resolveCycleStatus, + todayIso, +} from '../../utils/format.ts'; +import PopulationTrendChart from './PopulationTrendChart.tsx'; +import CountingAccuracyWarningBanner from './CountingAccuracyWarningBanner.tsx'; +import { getCountingAccuracyWarning } from '../../utils/countingAccuracyWarning.ts'; + +type Row = { + day: number; + date: string; + dateLabel: string; + stockAwal: number; + mati: number; + matiIot: number; + akurasiMati: number; + panen: number; + beratPanen: number; + stockAkhir: number; + chickenCount?: number; + persentase: number; + mortalityTotal: number; + harvestTotal: number; + harvestWeightTotal: number; + isEdited: boolean; + isToday: boolean; + isFuture: boolean; +}; + +function mortalityAccuracy(manual: number, iot: number): number { + if (manual === 0 && iot === 0) return 100; + const denom = Math.max(manual, iot); + if (denom <= 0) return 100; + return Math.round((Math.min(manual, iot) / denom) * 1000) / 10; +} + +const DataManagementPage: React.FC<{ onSettings: () => void }> = ({ onSettings }) => { + const { selectedCycle, selectedKandang, selectedSite } = useFarm(); + const [kpis, setKpis] = useState([]); + const [countings, setCountings] = useState([]); + const [manualRows, setManualRows] = useState([]); + const [insights, setInsights] = useState([]); + const [loading, setLoading] = useState(false); + const [syncing, setSyncing] = useState(false); + const [error, setError] = useState(null); + const [notice, setNotice] = useState(null); + const [searchDay, setSearchDay] = useState(''); + const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc'); + + const isClosedCycle = !selectedCycle || resolveCycleStatus(selectedCycle) !== 'active'; + + const loadData = useCallback(async (cycleId: number) => { + setLoading(true); + setError(null); + try { + const [k, c, m, i] = await Promise.all([ + api.kpis.list({ cycle_id: cycleId }), + api.countings.list({ cycle_id: cycleId }), + api.manualInputs.list({ cycle_id: cycleId }), + api.insights.list({ cycle_id: cycleId }), + ]); + setKpis(k); + setCountings(c); + setManualRows(m); + setInsights(i); + } catch (err) { + setError(errorMessage(err)); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + if (!selectedCycle) { + setKpis([]); + setCountings([]); + setManualRows([]); + setInsights([]); + return; + } + void loadData(selectedCycle.id); + }, [selectedCycle, loadData]); + + const handleSync = useCallback(async () => { + if (!selectedCycle) return; + setSyncing(true); + setError(null); + setNotice(null); + try { + await api.countings.sync({ cycle_id: selectedCycle.id }); + setNotice('Sinkron chicken counting edge berhasil.'); + await loadData(selectedCycle.id); + } catch (err) { + setError(errorMessage(err)); + } finally { + setSyncing(false); + } + }, [selectedCycle, loadData]); + + // Build daily rows through calendar today (not publish-gated current_day). + const rows = useMemo(() => { + if (!selectedCycle) return []; + + const countingByDate = new Map(countings.map((c) => [c.date, c])); + const manualByDate = new Map(manualRows.map((m) => [m.date, m])); + const kpiByDate = new Map(kpis.map((k) => [k.date, k])); + + const lastCycleDay = Math.max(0, (selectedCycle.total_days || 1) - 1); + const endDay = cycleDayForDate(selectedCycle.start_date, selectedCycle.end_date); + const calendarDay = cycleDayForDate(selectedCycle.start_date, todayIso()); + const maxDay = Math.min(calendarDay, lastCycleDay, endDay); + const today = todayIso(); + + let previousStockAkhir = 0; + let cumulativeMortality = 0; + let cumulativeHarvest = 0; + let cumulativeHarvestWeight = 0; + const result: Row[] = []; + + for (let day = 0; day <= maxDay; day++) { + const date = addDaysIso(selectedCycle.start_date, day); + const kpi = kpiByDate.get(date); + const manual = manualByDate.get(date); + const counting = countingByDate.get(date); + + const stockAwal = day === 0 ? selectedCycle.doc_in_count || 0 : previousStockAkhir; + const mati = manual?.mortality_manual ?? kpi?.mortality ?? 0; + const matiIot = counting?.mortality_count ?? 0; + const akurasiMati = mortalityAccuracy(mati, matiIot); + const panen = manual?.harvest_manual ?? kpi?.harvest ?? 0; + // Database menyimpan berat panen dalam gram; tampilkan selalu dalam kg. + const beratPanen = (manual?.harvest_weight_manual ?? kpi?.harvest_weight ?? 0) / 1000; + const stockAkhir = kpi?.chicken_life ?? Math.max(0, stockAwal - mati - panen); + + const chickenCount = counting?.total_count; + // Akurasi Chicken Counting (IOT) terhadap stock akhir manual: + // (nilai kecil / nilai besar) × 100%. Tanpa data IOT, tetap 0 (tampil "-"). + const persentase = + chickenCount !== undefined && chickenCount !== null && stockAkhir > 0 + ? (Math.min(chickenCount, stockAkhir) / Math.max(chickenCount, stockAkhir)) * 100 + : 0; + + cumulativeMortality += mati; + cumulativeHarvest += panen; + cumulativeHarvestWeight += beratPanen; + + result.push({ + day, + date, + dateLabel: formatDateId(date), + stockAwal, + mati, + matiIot, + akurasiMati, + panen, + beratPanen, + stockAkhir, + chickenCount, + persentase: Math.round(persentase * 10) / 10, + mortalityTotal: kpi?.mortality_total ?? cumulativeMortality, + harvestTotal: kpi?.harvest_total ?? cumulativeHarvest, + harvestWeightTotal: + kpi?.harvest_weight_total !== undefined + ? kpi.harvest_weight_total / 1000 + : cumulativeHarvestWeight, + isEdited: !!manual, + isToday: date === today, + isFuture: date > today, + }); + + previousStockAkhir = stockAkhir; + } + + return result; + }, [kpis, countings, manualRows, selectedCycle]); + + const stats = useMemo(() => { + const initialPopulation = selectedCycle?.doc_in_count || 0; + const latest = rows[rows.length - 1]; + const totalMortality = latest?.mortalityTotal ?? 0; + const totalPanen = latest?.harvestTotal ?? 0; + const totalBeratPanen = latest?.harvestWeightTotal ?? 0; + const currentPopulation = latest?.stockAkhir ?? initialPopulation; + const mortalityRate = initialPopulation + ? ((totalMortality / initialPopulation) * 100).toFixed(2) + : '0.00'; + + return { + initialPopulation, + totalMortality, + currentPopulation, + totalPanen, + totalBeratPanen, + mortalityRate, + }; + }, [rows, selectedCycle]); + + const chartData = useMemo( + () => + rows.map((r) => ({ + date: r.dateLabel, + population: r.stockAkhir, + chickenCount: r.chickenCount ?? undefined, + })), + [rows] + ); + + const countingAccuracyWarning = useMemo(() => { + if (!selectedCycle) return null; + return getCountingAccuracyWarning({ + cycle: selectedCycle, + countings, + kpis, + manualInputs: manualRows, + }); + }, [selectedCycle, countings, kpis, manualRows]); + + const filteredRecords = useMemo(() => { + let filtered = rows; + if (searchDay) { + const searchNum = parseInt(searchDay, 10); + if (!Number.isNaN(searchNum)) { + filtered = filtered.filter((r) => r.day === searchNum); + } + } + return [...filtered].sort((a, b) => (sortOrder === 'asc' ? a.day - b.day : b.day - a.day)); + }, [rows, searchDay, sortOrder]); + + const getPersentaseBadge = (persentase: number) => { + if (!persentase) return -; + + const isGreen = persentase >= 95; + const isYellow = persentase >= 90 && persentase < 95; + const colorClass = isGreen + ? 'bg-green-100 text-green-700' + : isYellow + ? 'bg-yellow-100 text-yellow-700' + : 'bg-red-100 text-red-700'; + + return ( + + {persentase.toFixed(1)}% + + ); + }; + + const getAkurasiMatiBadge = (akurasi: number) => { + const isGreen = akurasi >= 95; + const isYellow = akurasi >= 90 && akurasi < 95; + const colorClass = isGreen + ? 'bg-green-100 text-green-700' + : isYellow + ? 'bg-yellow-100 text-yellow-700' + : 'bg-red-100 text-red-700'; + + return ( + + {akurasi.toFixed(1)}% + + ); + }; + + if (!selectedCycle) return ; + + return ( +
+ {/* Header */} + } + subtitle={`Lihat data deplesi harian untuk siklus produksi · ${selectedSite?.site_name ?? ''} · ${selectedKandang?.kandang_name ?? ''} · Siklus ${formatDateRange(selectedCycle.start_date, selectedCycle.end_date)}`} + actions={ + + } + /> + + {countingAccuracyWarning && ( + + )} + + {/* AI Insight */} +
+

+ + AI Insight +

+ {insights.length === 0 ? ( + Belum ada insight untuk siklus ini. + ) : ( +
+ {insights.slice(0, 4).map((item) => ( +
+
+
+

{item.section}

+

{item.alert || 'Insight'}

+
+ {item.session} +
+

+ {item.insight_text} +

+
+ ))} +
+ )} +
+ + {/* Population Chart */} +
+ +
+ + {error && ( +
+ {error} +
+ )} + {notice && ( +
+ {notice} +
+ )} + + {/* Statistics Cards */} +
+
+
+
+

Populasi Awal

+

+ {formatNumber(stats.initialPopulation, 0)} +

+
+ +
+
+ +
+
+
+

Populasi Saat Ini

+

+ {formatNumber(stats.currentPopulation, 0)} +

+
+ +
+
+ +
+
+
+

Total Mortalitas

+

+ {formatNumber(stats.totalMortality, 0)} +

+
+ +
+
+ +
+
+
+

Total Panen

+

+ {formatNumber(stats.totalPanen, 0)} ekor +

+

+ {formatNumber(stats.totalBeratPanen, 2)} kg +

+
+ +
+
+ +
+
+
+

Tingkat Mortalitas

+

{stats.mortalityRate}%

+
+ +
+
+
+ + {loading ? ( + + ) : ( + <> + {/* Filters and Sorting */} +
+
+
+ + setSearchDay(e.target.value)} + placeholder="Masukkan nomor hari..." + className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" + /> +
+
+
+ + +
+
+
+
+ + {isClosedCycle && ( +
+
+ +
+

+ Mode Lihat Saja (Siklus Selesai) +

+
+
+
+ )} + + {/* Data Table */} +
+
+ {filteredRecords.length === 0 ? ( +
+ + Tidak ada data yang ditemukan +
+ ) : ( + filteredRecords.map((record) => { + const cardTone = record.isToday + ? 'ring-2 ring-blue-200 bg-blue-50/40' + : record.panen > 0 + ? 'ring-1 ring-purple-200 bg-white' + : 'bg-white'; + + return ( +
+
+
+
+ + Hari {record.day} + + {record.isToday && ( + + Hari ini + + )} + {record.isFuture && ( + + Mendatang + + )} + {record.isEdited && ( + + Diubah + + )} +
+
+ {record.dateLabel} +
+
+
+ +
+
+
+
+ Stock awal +
+
+ {formatNumber(record.stockAwal, 0)} +
+
+ +
+
+ Mati +
+
+ {formatNumber(record.mati, 0)} +
+
+ +
+
+ Mati IoT +
+
+ {formatNumber(record.matiIot, 0)} +
+
+ +
+
+ Akurasi Mati +
+
{getAkurasiMatiBadge(record.akurasiMati)}
+
+ +
+
+ Panen +
+
+ {formatNumber(record.panen, 0)} +
+
+ +
+
+ Berat panen (kg) +
+
+ {record.beratPanen ? formatNumber(record.beratPanen, 2) : '0.00'} kg +
+
+ +
+
+ Stock akhir +
+
+ {formatNumber(record.stockAkhir, 0)} +
+
+ +
+
+ Chicken Counting +
+
+ {record.chickenCount !== undefined + ? formatNumber(record.chickenCount, 0) + : '-'} +
+
+ +
+
+ Persentase +
+
{getPersentaseBadge(record.persentase)}
+
+
+
+
+ ); + }) + )} +
+ +
+
+ + + {/* Top header row with grouped columns */} + + + + + + + + + + {/* Second header row with individual column names */} + + + + + + + + + + + {filteredRecords.length === 0 ? ( + + + + ) : ( + filteredRecords.map((record, index) => { + const rowClass = `hover:bg-gray-100 transition-colors ${ + index % 2 === 0 ? 'bg-white' : 'bg-gray-50' + } ${record.panen > 0 ? 'border-l-4 border-purple-400' : ''}`; + + return ( + + {/* Hari */} + + + {/* Tanggal */} + + + {/* Stock awal */} + + + {/* Mati */} + + + {/* Mati IoT */} + + + {/* Akurasi Mati */} + + + {/* JUMLAH PANEN */} + + + {/* BERAT PANEN */} + + + {/* Stock akhir */} + + + {/* Chicken Counting */} + + + {/* Persentase */} + + + ); + }) + )} + +
+ Hari + + Tanggal + + Deplesi Daily + + PANEN + + Stock akhir + + Chicken Counting (IOT) + + Persentase +
+ Stock awal + + Mati + + Mati IoT + + Akurasi Mati + + JUMLAH PANEN + + BERAT PANEN (KG) +
+ + Tidak ada data yang ditemukan +
+ + {record.day} + + + {record.dateLabel} + + {formatNumber(record.stockAwal, 0)} + + + {formatNumber(record.mati, 0)} + + + + {formatNumber(record.matiIot, 0)} + + + {getAkurasiMatiBadge(record.akurasiMati)} + + + {formatNumber(record.panen, 0)} + + + + {record.beratPanen ? formatNumber(record.beratPanen, 2) : '0.00'} + + + {formatNumber(record.stockAkhir, 0)} + + + {record.chickenCount !== undefined + ? formatNumber(record.chickenCount, 0) + : '-'} + + + {getPersentaseBadge(record.persentase)} +
+
+
+
+ + {/* Info Section */} +
+
+
+ +
+
+

Informasi

+
    +
  • + Data hanya ditampilkan hingga + hari ini (dihitung dari tanggal mulai siklus) +
  • +
  • + + Hari 0: Stock awal = Jumlah DOC In (ayam masuk) +
  • +
  • + + Hari 1+: Stock awal = Stock akhir hari sebelumnya +
  • +
  • + + Stock akhir = Stock awal - Mati - panen (otomatis terhitung) +
  • +
  • + + Mati: Mortalitas harian manual | Mati IoT:{' '} + mortalitas dari edge API (kosong = 0) +
  • +
  • + + Akurasi Mati = (nilai kecil / nilai besar) × 100% antara Mati + manual dan Mati IoT (keduanya 0 → 100%) +
  • +
  • + + panen: Ayam dipanen +
  • +
  • + + Persentase = (nilai kecil / nilai besar) × 100% untuk konsep + akurasi hitungan IOT terhadap stock akhir manual +
  • +
  • + + Chicken Counting (IOT) = hasil hitung otomatis dari IOT +
  • +
  • + Baris dengan border ungu + menandakan ada panen pada hari tersebut +
  • +
+
+
+
+ + )} +
+ ); +}; + +export default DataManagementPage; diff --git a/components/counting/PopulationTrendChart.tsx b/components/counting/PopulationTrendChart.tsx new file mode 100644 index 0000000..cb23aef --- /dev/null +++ b/components/counting/PopulationTrendChart.tsx @@ -0,0 +1,119 @@ +import React from 'react'; +import { + CartesianGrid, + Line, + LineChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import { formatNumber } from '../../utils/format.ts'; + +export type PopulationPoint = { + date: string; + population: number; + chickenCount?: number; +}; + +type Props = { + data: PopulationPoint[]; + title?: string; +}; + +function yTick(value: number): string { + if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}jt`; + if (value >= 1_000) return `${Math.round(value / 1_000)}rb`; + return `${value}`; +} + +const PopulationTrendChart: React.FC = ({ data, title = 'Tren Populasi' }) => { + if (!data || data.length === 0) { + return ( +
+

{title}

+
+
+ +

Tidak ada data tersedia

+
+
+
+ ); + } + + return ( +
+

{title}

+ + {/* Legend: explicit color explanation */} +
+ + + Populasi (Stock Akhir Manual) + + + + Chicken Counting (IOT) + +
+ +
+ + + + + + { + const num = Number(value ?? 0); + return [num === 0 ? '0' : formatNumber(num, 0), name]; + }} + labelStyle={{ fontWeight: 600, marginBottom: '4px' }} + /> + + + + +
+ +

+ + Garis merah = populasi hasil perhitungan + manual (stock akhir), garis biru = + hasil hitung otomatis sensor IOT. Semakin berdekatan kedua garis, semakin akurat hitungan + IOT. +

+
+ ); +}; + +export default PopulationTrendChart; diff --git a/components/counting/__tests__/CountingAccuracyWarningBanner.test.tsx b/components/counting/__tests__/CountingAccuracyWarningBanner.test.tsx new file mode 100644 index 0000000..a7c4697 --- /dev/null +++ b/components/counting/__tests__/CountingAccuracyWarningBanner.test.tsx @@ -0,0 +1,36 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; +import CountingAccuracyWarningBanner from '../CountingAccuracyWarningBanner.tsx'; +import type { CountingAccuracyWarning } from '../../../utils/countingAccuracyWarning.ts'; + +const base: CountingAccuracyWarning = { + day: 2, + date: '2026-08-12', + iotCount: 900, + stockAkhir: 1000, + accuracy: 90, + ratioPercent: 90, + direction: 'under', +}; + +describe('CountingAccuracyWarningBanner', () => { + it('renders under-count manager checklist', () => { + render(); + expect(screen.getByText(/IoT lebih rendah dari stock/i)).toBeInTheDocument(); + expect(screen.getByText(/video kamera lengkap/i)).toBeInTheDocument(); + expect(screen.getByText(/Hari 2/i)).toBeInTheDocument(); + expect(screen.getByText(/90%/)).toBeInTheDocument(); + }); + + it('renders over-count fraud / AI checklist', () => { + render( + + ); + expect(screen.getByText(/lebih tinggi dari stock manual/i)).toBeInTheDocument(); + expect(screen.getByText(/fraud/i)).toBeInTheDocument(); + expect(screen.getByText(/akurasi 94,3%/i)).toBeInTheDocument(); + expect(screen.queryByText(/106%/)).not.toBeInTheDocument(); + }); +}); diff --git a/components/counting/__tests__/DataManagementPage.test.tsx b/components/counting/__tests__/DataManagementPage.test.tsx new file mode 100644 index 0000000..b537024 --- /dev/null +++ b/components/counting/__tests__/DataManagementPage.test.tsx @@ -0,0 +1,180 @@ +import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import DataManagementPage from '../DataManagementPage.tsx'; +import { api } from '../../../services/apiClient.ts'; + +vi.mock('../../../services/apiClient.ts', () => ({ + api: { + kpis: { + list: vi.fn().mockResolvedValue([]), + }, + countings: { + list: vi.fn().mockResolvedValue([]), + create: vi.fn(), + update: vi.fn(), + sync: vi.fn().mockResolvedValue({ upserted: 2, dates: ['2026-09-02', '2026-09-03'] }), + }, + manualInputs: { + list: vi.fn().mockResolvedValue([ + { + id: 1, + cycle: 1, + date: '2026-08-10', + mortality_manual: 10, + mortality_manual_total: 10, + harvest_manual: 0, + harvest_weight_manual: 0, + }, + ]), + create: vi.fn(), + }, + insights: { + list: vi.fn().mockResolvedValue([]), + }, + }, + errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), +})); + +vi.mock('../../../context/FarmContext.tsx', () => ({ + useFarm: () => ({ + selectedSite: { id: 1, site_name: 'Sukawarna', user: 1, created_at: '', updated_at: '' }, + selectedKandang: { + id: 1, + kandang_name: 'Kandang 1', + site: 1, + created_at: '', + updated_at: '', + }, + selectedCycle: { + id: 1, + kandang: 1, + flock: 1, + total_days: 35, + current_day: 1, + visible_through_date: '2026-08-10', + start_date: '2026-08-10', + end_date: '2026-09-13', + chick_in_weight: 45, + doc_in_count: 20000, + doc_in_weight: 45, + status: 'gm', + created_at: '', + updated_at: '', + }, + }), +})); + +vi.mock('../../../utils/format.ts', async () => { + const actual = await vi.importActual( + '../../../utils/format.ts' + ); + return { + ...actual, + todayIso: () => '2026-08-12', + }; +}); + +describe('DataManagementPage', () => { + beforeEach(() => { + vi.mocked(api.kpis.list).mockResolvedValue([]); + vi.mocked(api.countings.list).mockResolvedValue([]); + vi.mocked(api.countings.sync).mockResolvedValue({ + upserted: 2, + dates: ['2026-09-02', '2026-09-03'], + }); + }); + + it('renders the Hitung Ayam dashboard view with stats and daily rows', async () => { + render( undefined} />); + + expect(await screen.findByRole('heading', { name: 'Hitung Ayam' })).toBeInTheDocument(); + expect(screen.getByText(/Populasi Awal/i)).toBeInTheDocument(); + expect(screen.getByText(/Total Mortalitas/i)).toBeInTheDocument(); + expect(screen.getByText(/Tingkat Mortalitas/i)).toBeInTheDocument(); + expect(screen.getAllByText(/Hari 0/i).length).toBeGreaterThan(0); + expect(screen.getAllByText(/Hari 2/i).length).toBeGreaterThan(0); + }); + + it('does not offer manual or counting input forms', async () => { + render( undefined} />); + + expect(await screen.findByRole('heading', { name: 'Hitung Ayam' })).toBeInTheDocument(); + expect(screen.queryByRole('heading', { name: /Input manual/i })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: /Simpan hitungan/i })).not.toBeInTheDocument(); + expect(screen.queryByRole('button', { name: /Edit/i })).not.toBeInTheDocument(); + }); + + it('shows Mati IoT as 0 and Akurasi Mati when counting row is missing', async () => { + render( undefined} />); + + expect(await screen.findByRole('heading', { name: 'Hitung Ayam' })).toBeInTheDocument(); + expect(screen.getAllByText('Mati IoT').length).toBeGreaterThan(0); + expect(screen.getAllByText('Akurasi Mati').length).toBeGreaterThan(0); + // manual 10 vs iot 0 → 0.0% + expect(screen.getAllByText('0.0%').length).toBeGreaterThan(0); + }); + + it('calls chicken counting sync when Sync is clicked', async () => { + render( undefined} />); + + await screen.findByRole('heading', { name: 'Hitung Ayam' }); + fireEvent.click(screen.getByRole('button', { name: /Sync/i })); + + await waitFor(() => { + expect(api.countings.sync).toHaveBeenCalledWith({ cycle_id: 1 }); + }); + }); + + it('shows under-count IoT accuracy warning for the latest IoT day', async () => { + vi.mocked(api.kpis.list).mockResolvedValue([ + { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-12', + age: 2, + mortality: 0, + mortality_total: 10, + feed: 0, + feed_total: 0, + harvest: 0, + harvest_total: 0, + harvest_weight: 0, + harvest_weight_total: 0, + chicken_life: 19990, + chicken_life_percentage: 99.95, + iot_weight: 0, + average_harvest_day: 0, + average_harvest_weight: 0, + fcr: 0, + eef: 0, + cc: 0, + cw: 0, + fs: 0, + manual: 0, + created_at: '', + updated_at: '', + }, + ]); + vi.mocked(api.countings.list).mockResolvedValue([ + { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-12', + total_count: 18000, + mortality_count: 0, + created_at: '', + updated_at: '', + }, + ]); + + render( undefined} />); + + const alert = await screen.findByRole('alert'); + expect(within(alert).getByText(/IoT lebih rendah dari stock/i)).toBeInTheDocument(); + expect(within(alert).getByText(/Hari 2/i)).toBeInTheDocument(); + }); +}); diff --git a/components/dashboard/DashboardReportCtas.tsx b/components/dashboard/DashboardReportCtas.tsx new file mode 100644 index 0000000..8021d00 --- /dev/null +++ b/components/dashboard/DashboardReportCtas.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +export interface DashboardReportCtasProps { + cycleClosed: boolean; + hasDailySnapshot: boolean; + hasEndCycleSnapshot: boolean; + onOpenDaily: () => void; + onOpenEndCycle: () => void; +} + +const buttonClass = + 'rounded-lg bg-slate-900 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-slate-800 disabled:cursor-not-allowed disabled:bg-slate-400 disabled:hover:bg-slate-400'; + +const label = (hasSnapshot: boolean) => (hasSnapshot ? 'Lihat' : 'Buat'); + +const DashboardReportCtas: React.FC = ({ + cycleClosed, + hasDailySnapshot, + hasEndCycleSnapshot, + onOpenDaily, + onOpenEndCycle, +}) => ( +
+
+ + +
+ {!cycleClosed && ( +

Tersedia setelah siklus ditutup

+ )} +
+); + +export default DashboardReportCtas; diff --git a/components/dashboard/KandangRankingTop5.tsx b/components/dashboard/KandangRankingTop5.tsx new file mode 100644 index 0000000..5c1b6fb --- /dev/null +++ b/components/dashboard/KandangRankingTop5.tsx @@ -0,0 +1,116 @@ +import React, { useEffect, useState } from 'react'; +import { errorMessage } from '../../services/apiClient.ts'; +import type { View } from '../../types/common.ts'; +import { useFarm } from '../../context/FarmContext.tsx'; +import { Banner, Spinner } from '../ui/Feedback.tsx'; +import { formatRatio } from '../../utils/format.ts'; +import { + loadKandangRanking, + type KandangRankingRow, +} from '../../utils/kandangRanking.ts'; + +type Props = { + setView: (view: View) => void; +}; + +const KandangRankingTop5: React.FC = ({ setView }) => { + const { + selectedSite, + setSelectedSiteId, + setSelectedKandangId, + setSelectedCycleId, + } = useFarm(); + const [rows, setRows] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const openEef = (row: KandangRankingRow) => { + setSelectedSiteId(row.siteId); + setSelectedKandangId(row.kandangId); + setSelectedCycleId(row.cycleId); + setView('eefDashboard'); + }; + + useEffect(() => { + if (!selectedSite) { + setRows([]); + setError(null); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const next = await loadKandangRanking({ sites: [selectedSite], months: 3 }); + if (!cancelled) setRows(next.slice(0, 5)); + } catch (err) { + if (!cancelled) { + setError(errorMessage(err)); + setRows([]); + } + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [selectedSite]); + + if (!selectedSite) return null; + + return ( +
+
+
+

Peringkat EEF

+

+ Top 5 · {selectedSite.site_name} · 3 bulan terakhir (siklus tertutup) +

+
+ +
+ + {error && {error}} + {loading ? ( + + ) : rows.length === 0 ? ( +

Tidak ada siklus tertutup dalam 3 bulan terakhir.

+ ) : ( +
    + {rows.map((row) => ( +
  • openEef(row)} + > +
    + + {row.rank > 0 ? row.rank : '—'} + +
    +

    {row.kandangName}

    +

    + FCR {row.fcr == null ? 'N/A' : formatRatio(row.fcr, 3)} +

    +
    +
    +

    + {row.eef == null ? 'N/A' : formatRatio(row.eef, 3)} +

    +
  • + ))} +
+ )} +
+ ); +}; + +export default KandangRankingTop5; diff --git a/components/dashboard/ReportPreviewOverlay.tsx b/components/dashboard/ReportPreviewOverlay.tsx new file mode 100644 index 0000000..9667ec0 --- /dev/null +++ b/components/dashboard/ReportPreviewOverlay.tsx @@ -0,0 +1,639 @@ +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { api, errorMessage } from '../../services/apiClient.ts'; +import { useFarm } from '../../context/FarmContext.tsx'; +import { buildInMemoryReport } from '../../utils/buildInMemoryReport.ts'; +import { downloadReportExcel } from '../../utils/reportExcel.ts'; +import { exportElementToPdf } from '../../utils/pdfExport.ts'; +import { + countingTotals, + feedInTotals, + feedOutTotals, + feedUseTotals, +} from '../../utils/reportTotals.ts'; +import { + cycleDayForDate, + formatDateId, + formatDateRange, + formatNumber, + formatRatio, +} from '../../utils/format.ts'; +import { buildReportSummary, formatSummaryValue } from '../../utils/reportSummary.ts'; +import type { DashboardReportPayload, DashboardReportType } from '../../types/dashboardReport.ts'; +import { Banner } from '../ui/Feedback.tsx'; + +type Props = { + open: boolean; + reportType: DashboardReportType; + onClose: () => void; +}; + +const cell = (value: number | string | null | undefined, suffix = ''): string => { + if (value === null || value === undefined || value === '') return 'N/A'; + if (typeof value === 'number' && !Number.isFinite(value)) return 'N/A'; + return `${value}${suffix}`; +}; + +const dashCell = (value: number | null | undefined): string => + value == null || !Number.isFinite(value) ? '-' : String(value); + +const accuracyCell = (value: number | null | undefined): string => + value == null || !Number.isFinite(value) ? 'N/A' : `${value.toFixed(1)}%`; + +const ratioCell = (value: number | null | undefined): string => + value == null || !Number.isFinite(value) ? 'N/A' : formatRatio(Number(value), 3); + +const qtyCell = (value: number | null | undefined, maxDecimals = 0, suffix = ''): string => { + if (value == null || !Number.isFinite(value)) return 'N/A'; + return `${formatNumber(Number(value), maxDecimals, 0, true)}${suffix}`; +}; + +const harvestKgCell = (grams: number | null | undefined): string => { + if (grams == null || !Number.isFinite(grams)) return 'N/A'; + return `${formatNumber(Number(grams) / 1000, 1)} kg`; +}; + +const ReportPreviewOverlay: React.FC = ({ open, reportType, onClose }) => { + const { selectedCycle, selectedKandang, selectedSite } = useFarm(); + const isEndCycle = reportType === 'end_cycle'; + const [draftDay, setDraftDay] = useState(0); + const [payload, setPayload] = useState(null); + const [generating, setGenerating] = useState(false); + const [error, setError] = useState(null); + const printRef = useRef(null); + + const latestDay = selectedCycle ? Math.max(0, selectedCycle.current_day) : 0; + const endCycleDay = selectedCycle + ? Math.min( + selectedCycle.total_days, + cycleDayForDate(selectedCycle.start_date, selectedCycle.end_date) + ) + : 0; + const effectiveUpToDay = isEndCycle ? endCycleDay : draftDay; + + const dayOptions = useMemo( + () => Array.from({ length: latestDay + 1 }, (_, day) => day), + [latestDay] + ); + + useEffect(() => { + if (!open) return; + setPayload(null); + setError(null); + setGenerating(false); + setDraftDay(isEndCycle ? endCycleDay : latestDay); + }, [open, isEndCycle, latestDay, endCycleDay]); + + const generate = useCallback(async () => { + if (!selectedCycle || !selectedKandang) return; + setGenerating(true); + setError(null); + try { + const cycleId = selectedCycle.id; + const [countings, manuals, weights, karungs, kpis] = await Promise.all([ + api.countings.list({ cycle_id: cycleId }), + api.manualInputs.list({ cycle_id: cycleId }), + api.weights.list({ cycle_id: cycleId }), + api.karungs.list({ cycle_id: cycleId }), + api.kpis.list({ cycle_id: cycleId }), + ]); + const next = buildInMemoryReport({ + cycle: selectedCycle, + kandangId: selectedKandang.id, + kandangName: selectedKandang.kandang_name, + area: selectedSite?.site_name ?? '', + reportType, + countings, + manuals, + weights, + karungs, + kpis, + upToDay: effectiveUpToDay, + }); + setPayload(next); + } catch (err) { + setError(errorMessage(err)); + } finally { + setGenerating(false); + } + }, [reportType, selectedCycle, selectedKandang, selectedSite, effectiveUpToDay]); + + const downloadPdf = useCallback(async () => { + if (!printRef.current || !payload) return; + const period = isEndCycle ? 'Akhir-Siklus' : `Harian-Hari-${payload.upToDay}`; + const filename = `Laporan-${period}-${payload.area}-${payload.kandangName}-${payload.cycleStart}_sd_${payload.cycleEnd}.pdf`; + await exportElementToPdf(printRef.current, filename); + }, [payload, isEndCycle]); + + const summary = useMemo( + () => (payload ? buildReportSummary(payload) : null), + [payload] + ); + + if (!open) return null; + + const title = isEndCycle ? 'Laporan Akhir Siklus' : 'Laporan Harian'; + const cycleLabel = selectedCycle + ? `Siklus ${formatDateRange(selectedCycle.start_date, selectedCycle.end_date)}` + : ''; + const countingTotal = countingTotals(payload?.counting || []); + const feedInTotal = feedInTotals(payload?.feedIn || []); + const feedUseTotal = feedUseTotals(payload?.feedUse || []); + const feedOutTotal = feedOutTotals(payload?.feedOut || []); + const endDateLabel = selectedCycle ? formatDateId(selectedCycle.start_date) : ''; + const dataDates = + selectedCycle && payload + ? `(${endDateLabel} - ${formatDateId(payload.counting[payload.counting.length - 1]?.date ?? selectedCycle.start_date)})` + : ''; + const cycleRange = selectedCycle + ? formatDateRange(selectedCycle.start_date, selectedCycle.end_date) + : ''; + const printedDate = new Date().toLocaleDateString('id-ID', { + day: 'numeric', + month: 'long', + year: 'numeric', + }); + + return ( +
+
+
+
+

+ {title} +

+

+ {selectedKandang?.kandang_name ?? 'Pilih kandang'} · {cycleLabel} · Hari ke-0 s/d ke- + {effectiveUpToDay} +

+
+
+ {!isEndCycle && ( + <> + + + + )} + + + + +
+
+ +
+ {error && ( +
+ {error} +
+ )} + +
+ {!payload ? ( +

+ Tekan Generate untuk membuat laporan dari data siklus saat ini. +

+ ) : ( + <> +
+
{title}
+
+ Lokasi: {payload.area} — {payload.kandangName} +
+
+ Periode: Hari ke-0 s/d ke-{payload.upToDay} {dataDates} +
+
+ Siklus: {cycleRange} +
+
+ Berat DOC:{' '} + {payload.docWeight == null || !Number.isFinite(payload.docWeight) + ? '—' + : `${formatNumber(payload.docWeight, 1, 0, true)} gram`} +
+
+ Dicetak: {printedDate} +
+
+ + {summary && ( +
+ {summary.metrics.map((metric) => { + const formattedValue = formatSummaryValue(metric); + const isHighlight = metric.key === 'fcr' || metric.key === 'eef'; + const columnPlacement = isHighlight + ? ({ + gridColumn: metric.key === 'fcr' ? 2 : 3, + marginTop: 12, + } as const) + : {}; + return ( +
+
+ {metric.label} +
+
+ {formattedValue} + {metric.unit && formattedValue !== '—' ? ( + + {metric.unit} + + ) : null} +
+
+ ); + })} +
+ )} + + + + + Tanggal + Umur (hari) + Stok awal + Mortalitas + Panen + Berat panen + Stok akhir + IoT + Akurasi % + + + + {payload.counting.map((row) => ( + + {formatDateId(row.date)} + {row.day} + {cell(row.countBefore)} + {cell(row.mortality)} + {cell(row.harvest)} + {cell(row.harvestWeight)} + {cell(row.countAfter)} + {cell(row.iotCount)} + {accuracyCell(row.accuracy)} + + ))} + + {countingTotal && ( + + + {countingTotal.label} + — + {dashCell(countingTotal.countBefore)} + {cell(countingTotal.mortality)} + {cell(countingTotal.harvest)} + {cell(countingTotal.harvestWeight)} + {dashCell(countingTotal.countAfter)} + {dashCell(countingTotal.iotCount)} + + {countingTotal.accuracy == null + ? '-' + : accuracyCell(countingTotal.accuracy)} + + + + )} + + + + + + Tanggal + Umur (hari) + Rata-rata manual + Rata-rata IoT + Keseragaman + Selisih + Akurasi % + + + + {payload.weight.map((row) => ( + + {formatDateId(row.date)} + {row.day} + {cell(row.avgManual)} + {cell(row.avgIot)} + {accuracyCell(row.uniformity)} + {cell(row.difference)} + {accuracyCell(row.accuracy)} + + ))} + + + + + + + Tanggal + Manual masuk + IoT masuk + Akurasi % + + + + {payload.feedIn.map((row) => ( + + {formatDateId(row.date)} + {cell(row.manualIn)} + {cell(row.iotIn)} + {accuracyCell(row.accuracy)} + + ))} + + {feedInTotal && ( + + + {feedInTotal.label} + {cell(feedInTotal.manualIn)} + {cell(feedInTotal.iotIn)} + {accuracyCell(feedInTotal.accuracy)} + + + )} + + + + + + Tanggal + Umur (hari) + Manual dituang + IoT dituang + Akurasi % + + + + {payload.feedUse.map((row) => ( + + {formatDateId(row.date)} + {row.day} + {cell(row.manualUse)} + {cell(row.iotUse)} + {accuracyCell(row.accuracy)} + + ))} + + {feedUseTotal && ( + + + {feedUseTotal.label} + — + {cell(feedUseTotal.manualUse)} + {cell(feedUseTotal.iotUse)} + {accuracyCell(feedUseTotal.accuracy)} + + + )} + + + + + + Tanggal + Manual keluar + IoT keluar + Akurasi % + + + + {payload.feedOut.map((row) => ( + + {formatDateId(row.date)} + {cell(row.manualOut)} + {cell(row.iotOut)} + {accuracyCell(row.accuracy)} + + ))} + + {feedOutTotal && ( + + + {feedOutTotal.label} + {cell(feedOutTotal.manualOut)} + {cell(feedOutTotal.iotOut)} + {accuracyCell(feedOutTotal.accuracy)} + + + )} + + + {isEndCycle && ( + <> + + + + Umur + Total Pakan + Bobot IoT + Ayam Hidup + Total Bobot Panen + FCR + + + + {payload.fcr.map((row) => ( + + Hari {row.day} + {qtyCell(row.feedTotal, 0, ' karung')} + {qtyCell(row.iotWeight, 2, row.iotWeight != null ? ' g' : '')} + {qtyCell(row.chickenLife, 0, ' ekor')} + {harvestKgCell(row.harvestWeightTotal)} + {ratioCell(row.iotFcr)} + + ))} + + + + + + + Umur + Persentase Ayam Hidup + BW Rata-rata Panen + Umur Rata-rata Panen + FCR + EEF + + + + {payload.eef.map((row) => ( + + Hari {row.day} + {qtyCell(row.chickenLifePercentage, 3, '%')} + + {qtyCell( + row.iotAverageHarvestBw, + 2, + row.iotAverageHarvestBw != null ? ' g' : '' + )} + + {qtyCell(row.iotAverageDayWeight, 2)} + {ratioCell(row.iotFcr)} + {ratioCell(row.iotEef)} + + ))} + + + + )} + + )} +
+
+
+
+ ); +}; + +const ReportTable: React.FC<{ + title: string; + children: React.ReactNode; + divided?: boolean; +}> = ({ title, children, divided = false }) => ( +
+

{title}

+
+ {children}
+
+
+); + +const Th: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + {children} +); + +const Td: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + {children} +); + +const TotalRow: React.FC<{ children: React.ReactNode }> = ({ children }) => ( + + {children} + +); + +export default ReportPreviewOverlay; diff --git a/components/dashboard/__tests__/DashboardReportCtas.test.tsx b/components/dashboard/__tests__/DashboardReportCtas.test.tsx new file mode 100644 index 0000000..a155ba9 --- /dev/null +++ b/components/dashboard/__tests__/DashboardReportCtas.test.tsx @@ -0,0 +1,21 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import DashboardReportCtas from '../DashboardReportCtas.tsx'; + +describe('DashboardReportCtas', () => { + it('disables end-cycle until the cycle is closed', () => { + const onOpenDaily = vi.fn(); + const onOpenEndCycle = vi.fn(); + render( + + ); + expect(screen.getByRole('button', { name: /Akhir Siklus/i })).toBeDisabled(); + fireEvent.click(screen.getByRole('button', { name: /Harian/i })); + expect(onOpenDaily).toHaveBeenCalled(); + }); +}); diff --git a/components/feedSack/FeedDailySummaryTable.tsx b/components/feedSack/FeedDailySummaryTable.tsx new file mode 100644 index 0000000..20f2db1 --- /dev/null +++ b/components/feedSack/FeedDailySummaryTable.tsx @@ -0,0 +1,265 @@ +import React, { useMemo, useRef, useState } from 'react'; +import type { Karung, ManualInput } from '../../types/api.ts'; +import { formatNumber } from '../../utils/format.ts'; + +type SortOrder = 'asc' | 'desc'; + +interface FeedDailySummaryTableProps { + rows: Karung[]; + manualRows: ManualInput[]; + cycleStartDate: string; + currentDay: number; +} + +const accuracyOf = (manual: number, iot: number): string => { + if (manual === 0 && iot === 0) return '100.0%'; + if (manual === 0 || iot === 0) return '0.0%'; + const smaller = Math.min(manual, iot); + const larger = Math.max(manual, iot); + return `${((smaller / larger) * 100).toFixed(1)}%`; +}; + +const accuracyClass = (manual: number, iot: number): string => { + if (manual === 0 && iot === 0) return 'text-green-600'; + if (manual === 0 || iot === 0) return 'text-red-600'; + const percentage = (Math.min(manual, iot) / Math.max(manual, iot)) * 100; + if (percentage >= 95) return 'text-green-600'; + if (percentage >= 80) return 'text-yellow-600'; + return 'text-red-600'; +}; + +const FeedDailySummaryTable: React.FC = ({ + rows, + manualRows, + cycleStartDate, + currentDay, +}) => { + const [sortOrder, setSortOrder] = useState('desc'); + + const masukRef = useRef(null); + const tuangRef = useRef(null); + const keluarRef = useRef(null); + + const scrollToSection = (ref: React.RefObject) => { + ref.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + }; + + const aggregatedData = useMemo(() => { + const cycleStart = new Date(`${cycleStartDate}T00:00:00`); + const iotByDate = new Map(); + for (const row of rows) iotByDate.set(row.date, row); + const manualByDate = new Map(); + for (const row of manualRows) manualByDate.set(row.date, row); + + const result: { + day: number; + date: Date; + dateFormatted: string; + iot: Karung | null; + manual: ManualInput | null; + }[] = []; + for (let d = 0; d <= currentDay; d++) { + const date = new Date(cycleStart); + date.setDate(cycleStart.getDate() + d); + const key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String( + date.getDate() + ).padStart(2, '0')}`; + result.push({ + day: d, + date, + dateFormatted: date.toLocaleDateString('id-ID', { + day: 'numeric', + month: 'short', + year: 'numeric', + }), + iot: iotByDate.get(key) ?? null, + manual: manualByDate.get(key) ?? null, + }); + } + return result; + }, [rows, manualRows, cycleStartDate, currentDay]); + + const sortedData = useMemo(() => { + const sorted = [...aggregatedData].sort((a, b) => a.day - b.day); + return sortOrder === 'desc' ? sorted.reverse() : sorted; + }, [aggregatedData, sortOrder]); + + if (aggregatedData.length === 0 || (rows.length === 0 && manualRows.length === 0)) { + return ( +
+

Rincian Harian Karung IOT

+
+
+ +

Tidak ada data

+

+ Belum ada data karung IOT untuk siklus ini. Sinkronkan lewat tombol Sync hari ini. +

+
+
+
+ ); + } + + const renderBox = ( + title: string, + emoji: string, + headerColor: string, + manualGetter: (row: ManualInput) => number, + iotGetter: (row: Karung) => number, + totalGetter: (row: Karung) => number, + ref: React.RefObject + ) => ( +
+ {/* Header */} +
+ {emoji} + {title} +
+ + {/* Table container with scroll */} +
+
+ + + + + + + + + + + + + {sortedData.map((summary) => { + const manualValue = summary.manual ? manualGetter(summary.manual) : 0; + const iotValue = summary.iot ? iotGetter(summary.iot) : 0; + const total = summary.iot ? totalGetter(summary.iot) : null; + return ( + + + + + + + + + ); + })} + +
HariTanggal + Manual + + IOT + + Akurasi + Total
+ + {summary.day} + + {summary.dateFormatted} + {formatNumber(manualValue)} + + {formatNumber(iotValue)} + + {accuracyOf(manualValue, iotValue)} + + {total == null ? '-' : formatNumber(total)} +
+
+
+
+ ); + + return ( +
+ {/* Header */} +
+

Rincian Harian Karung IOT

+ +
+ + {/* Sticky Quick Navigation Bar (Excel-style freeze) */} +
+
+
+ + + +
+
+
+ + {/* Three separate boxes */} + {renderBox( + 'KARUNG MASUK', + '🟢', + '#86efac', + (row) => row.feed_in_manual, + (row) => row.in_today, + (row) => row.in_total, + masukRef + )} + {renderBox( + 'KARUNG TUANG', + '🟠', + '#fdba74', + (row) => row.feed_use_manual, + (row) => row.feed_use_today, + (row) => row.feed_use_total, + tuangRef + )} + {renderBox( + 'KARUNG KELUAR', + '🔴', + '#fca5a5', + (row) => row.feed_out_manual, + (row) => row.out_today, + (row) => row.out_total, + keluarRef + )} +
+ ); +}; + +export default FeedDailySummaryTable; diff --git a/components/feedSack/FeedSaldoCard.tsx b/components/feedSack/FeedSaldoCard.tsx new file mode 100644 index 0000000..2982bbb --- /dev/null +++ b/components/feedSack/FeedSaldoCard.tsx @@ -0,0 +1,120 @@ +import React, { useMemo } from 'react'; +import type { Karung } from '../../types/api.ts'; +import { formatNumber } from '../../utils/format.ts'; + +interface FeedSaldoCardProps { + latest: Karung | null; + feedInitialBalance: number; + cycleStartDate: string; + displayDate: string; +} + +const FeedSaldoCard: React.FC = ({ + latest, + feedInitialBalance, + cycleStartDate, + displayDate, +}) => { + const saldoData = useMemo(() => { + const inbound = (latest?.in_total ?? 0) + feedInitialBalance; + const feedUse = latest?.feed_use_total ?? 0; + const keluar = latest?.out_total ?? 0; + const saldo = inbound - feedUse - keluar; + return { inbound, feedUse, keluar, saldo }; + }, [latest, feedInitialBalance]); + + const formatDateRange = useMemo(() => { + const formatDate = (iso: string) => + new Intl.DateTimeFormat('id-ID', { + day: 'numeric', + month: 'long', + year: 'numeric', + }).format(new Date(`${iso}T00:00:00`)); + return `${formatDate(cycleStartDate)} - ${formatDate(displayDate)}`; + }, [cycleStartDate, displayDate]); + + const getSaldoStatusColor = (saldo: number) => { + if (saldo > 0) return 'text-green-600'; + if (saldo < 0) return 'text-red-600'; + return 'text-gray-600'; + }; + + return ( +
+
+
+
+ +
+
+

Saldo Karung IOT

+

{formatDateRange}

+
+
+
+ + {/* Saldo Display */} +
+
+ {/* Karung Masuk */} +
+
+ +

Karung Masuk

+
+

{formatNumber(saldoData.inbound)}

+

karung

+
+ + {/* Karung Dituang (feed use) */} +
+
+ +

Karung Dituang

+
+

{formatNumber(saldoData.feedUse)}

+

karung

+
+ + {/* Karung Keluar */} +
+
+ +

Karung Keluar

+
+

{formatNumber(saldoData.keluar)}

+

karung

+
+ + {/* Saldo */} +
+
+ +

Saldo

+
+

+ {formatNumber(saldoData.saldo)} +

+

karung

+
+
+

+ Saldo = karung masuk − karung dituang − karung keluar. +

+
+ + {/* Warning for negative saldo */} + {saldoData.saldo < 0 && ( +
+ +

+ Peringatan: Saldo negatif menunjukkan karung dituang lebih banyak dari + karung masuk. Periksa kembali data sinkronisasi karung-web-admin. +

+
+ )} +
+ ); +}; + +export default FeedSaldoCard; diff --git a/components/feedSack/FeedStats.tsx b/components/feedSack/FeedStats.tsx new file mode 100644 index 0000000..3f0c618 --- /dev/null +++ b/components/feedSack/FeedStats.tsx @@ -0,0 +1,145 @@ +import React, { useMemo } from 'react'; +import type { Karung, ManualInput } from '../../types/api.ts'; +import { formatNumber } from '../../utils/format.ts'; + +const StatItem: React.FC<{ + icon: React.ReactNode; + label: string; + value: number | null; + colorOverride?: string; +}> = ({ icon, label, value, colorOverride }) => ( +
+
+
{icon}
+

+ {label} +

+
+
+

+ {value == null ? formatNumber(0) : formatNumber(value)} +

+

karung

+
+
+); + +interface FeedStatsProps { + latest: Karung | null; + latestManual: ManualInput | null; + cycleStartDate: string; + displayDate: string; +} + +const FeedStats: React.FC = ({ + latest, + latestManual, + cycleStartDate, + displayDate, +}) => { + const formatDisplayDate = (iso: string) => + new Intl.DateTimeFormat('id-ID', { + day: 'numeric', + month: 'long', + year: 'numeric', + }).format(new Date(`${iso}T00:00:00`)); + + const todayLabel = useMemo(() => formatDisplayDate(displayDate), [displayDate]); + + const totalCycleLabel = useMemo(() => { + const start = new Intl.DateTimeFormat('id-ID', { + day: 'numeric', + month: 'short', + }).format(new Date(`${cycleStartDate}T00:00:00`)); + const end = new Intl.DateTimeFormat('id-ID', { + day: 'numeric', + month: 'short', + }).format(new Date(`${displayDate}T00:00:00`)); + return `Total (${start} - ${end})`; + }, [cycleStartDate, displayDate]); + + const columns = useMemo( + () => [ + { + key: 'masuk', + title: 'Karung Masuk', + color: '#2563eb', + icon: , + iotToday: latest?.in_today ?? 0, + iotTotal: latest?.in_total ?? 0, + manualToday: latestManual?.feed_in_manual ?? 0, + manualTotal: latestManual?.feed_in_manual_total ?? 0, + }, + { + key: 'dituang', + title: 'Karung Dituang', + color: '#ea580c', + icon: , + iotToday: latest?.feed_use_today ?? 0, + iotTotal: latest?.feed_use_total ?? 0, + manualToday: latestManual?.feed_use_manual ?? 0, + manualTotal: latestManual?.feed_use_manual_total ?? 0, + }, + { + key: 'keluar', + title: 'Karung Keluar', + color: '#dc2626', + icon: , + iotToday: latest?.out_today ?? 0, + iotTotal: latest?.out_total ?? 0, + manualToday: latestManual?.feed_out_manual ?? 0, + manualTotal: latestManual?.feed_out_manual_total ?? 0, + }, + ], + [latest, latestManual] + ); + + return ( +
+
+ {columns.map((col) => ( +
+

+ {col.title} +

+
+
+ } + label={`IOT · ${todayLabel}`} + value={col.iotToday} + colorOverride={col.color} + /> + } + label={`IOT · ${totalCycleLabel}`} + value={col.iotTotal} + colorOverride={col.color} + /> +
+
+ } + label={`Manual · ${todayLabel}`} + value={col.manualToday} + colorOverride="#6b7280" + /> + } + label={`Manual · ${totalCycleLabel}`} + value={col.manualTotal} + colorOverride="#6b7280" + /> +
+
+
+ ))} +
+
+ ); +}; + +export default FeedStats; diff --git a/components/feedSack/FeedTrendChart.tsx b/components/feedSack/FeedTrendChart.tsx new file mode 100644 index 0000000..62e6a99 --- /dev/null +++ b/components/feedSack/FeedTrendChart.tsx @@ -0,0 +1,108 @@ +import React, { useMemo } from 'react'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, + ResponsiveContainer, +} from 'recharts'; +import type { Karung } from '../../types/api.ts'; + +interface FeedTrendChartProps { + rows: Karung[]; + cycleStartDate: string; + currentDay: number; +} + +const FeedTrendChart: React.FC = ({ rows, cycleStartDate, currentDay }) => { + const chartData = useMemo(() => { + const cycleStart = new Date(`${cycleStartDate}T00:00:00`); + + const dailyData: { label: string; masuk: number; dituang: number; keluar: number }[] = []; + for (let d = 0; d <= currentDay; d++) { + const date = new Date(cycleStart); + date.setDate(cycleStart.getDate() + d); + dailyData.push({ + label: date.toLocaleDateString('id-ID', { day: '2-digit', month: 'short' }), + masuk: 0, + dituang: 0, + keluar: 0, + }); + } + + const byKey = new Map(); + for (const row of rows) { + const bucket = byKey.get(row.date) ?? { masuk: 0, dituang: 0, keluar: 0 }; + bucket.masuk += row.in_today; + bucket.dituang += row.feed_use_today ?? 0; + bucket.keluar += row.out_today ?? 0; + byKey.set(row.date, bucket); + } + + for (let d = 0; d <= currentDay; d++) { + const date = new Date(cycleStart); + date.setDate(cycleStart.getDate() + d); + const key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String( + date.getDate() + ).padStart(2, '0')}`; + const bucket = byKey.get(key); + const entry = dailyData[d]; + if (bucket && entry) { + entry.masuk = bucket.masuk; + entry.dituang = bucket.dituang; + entry.keluar = bucket.keluar; + } + } + + return dailyData; + }, [rows, cycleStartDate, currentDay]); + + const seriesLabel = (name: string) => { + if (name === 'masuk') return 'Karung Masuk'; + if (name === 'dituang') return 'Karung Dituang'; + return 'Karung Keluar'; + }; + + return ( +
+

Tren Harian Karung IOT

+
+ + + + + + [ + `${Number(value ?? 0)} karung`, + seriesLabel(String(name)), + ]} + labelFormatter={(label) => `Tanggal: ${label}`} + /> + seriesLabel(String(value))} /> + + + + + +
+
+ ); +}; + +export default FeedTrendChart; diff --git a/components/feedSack/InitialBalanceCard.tsx b/components/feedSack/InitialBalanceCard.tsx new file mode 100644 index 0000000..802541c --- /dev/null +++ b/components/feedSack/InitialBalanceCard.tsx @@ -0,0 +1,132 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { api, errorMessage } from '../../services/apiClient.ts'; +import type { Cycle, InitialBalanceResult } from '../../types/api.ts'; +import { formatNumber } from '../../utils/format.ts'; +import InitialBalanceComparison from './InitialBalanceComparison.tsx'; + +interface InitialBalanceCardProps { + cycle: Cycle; +} + +const InitialBalanceCard: React.FC = ({ cycle }) => { + const savedBalanceDate = cycle.feed_initial_balance_date ?? cycle.start_date; + const [balanceDate, setBalanceDate] = useState(savedBalanceDate); + const [manualEntry, setManualEntry] = useState( + cycle.feed_initial_balance > 0 ? String(cycle.feed_initial_balance) : '' + ); + const [comparing, setComparing] = useState(false); + const [error, setError] = useState(null); + const [comparison, setComparison] = useState(null); + + useEffect(() => { + setBalanceDate(cycle.feed_initial_balance_date ?? cycle.start_date); + setManualEntry(cycle.feed_initial_balance > 0 ? String(cycle.feed_initial_balance) : ''); + setComparison(null); + setError(null); + }, [cycle.id, cycle.feed_initial_balance, cycle.feed_initial_balance_date, cycle.start_date]); + + const manualValue = manualEntry === '' ? null : Number(manualEntry); + + const loadComparison = useCallback(async () => { + if (balanceDate === '' || manualValue == null || Number.isNaN(manualValue) || manualValue < 0) { + setComparison(null); + return; + } + + setComparing(true); + setError(null); + try { + const compared = await api.cycles.initialBalanceCompare(cycle.id, { + date: balanceDate, + manual: manualValue, + }); + setComparison(compared); + } catch (err) { + setComparison(null); + setError(errorMessage(err)); + } finally { + setComparing(false); + } + }, [balanceDate, cycle.id, manualValue]); + + useEffect(() => { + if (manualValue == null || manualValue < 0) { + setComparison(null); + return; + } + void loadComparison(); + }, [loadComparison, manualValue]); + + return ( +
+
+
+ +
+
+

Saldo Awal

+

+ Masukkan saldo awal karung pakan pada tanggal tertentu, lalu bandingkan dengan deteksi + IoT. +

+
+
+ +
+
+
+ + setBalanceDate(event.target.value)} + className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" + /> +
+
+ + setManualEntry(event.target.value)} + placeholder="Contoh: 120" + className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm" + /> +
+
+ + {error && ( +

+ {error} +

+ )} + + {cycle.feed_initial_balance > 0 && comparison == null && ( +

+ Saldo awal tersimpan:{' '} + + {formatNumber(cycle.feed_initial_balance)} karung + +

+ )} + + {comparison && } +
+
+ ); +}; + +export default InitialBalanceCard; diff --git a/components/feedSack/InitialBalanceComparison.tsx b/components/feedSack/InitialBalanceComparison.tsx new file mode 100644 index 0000000..503a6b3 --- /dev/null +++ b/components/feedSack/InitialBalanceComparison.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import type { InitialBalanceResult } from '../../types/api.ts'; +import { formatNumber } from '../../utils/format.ts'; + +interface InitialBalanceComparisonProps { + result: InitialBalanceResult; + loading?: boolean; +} + +const InitialBalanceComparison: React.FC = ({ + result, + loading = false, +}) => { + const accuracy = result.accuracy; + const accuracyLabel = accuracy == null ? 'N/A' : `${formatNumber(accuracy, 1)}%`; + const accuracyColor = + accuracy == null + ? 'text-gray-500' + : accuracy >= 95 + ? 'text-green-600' + : accuracy >= 80 + ? 'text-yellow-600' + : 'text-red-600'; + + return ( +
+

+ Perbandingan {result.date} + {loading ? ' · memuat IoT...' : ''} +

+
+
+

Manual

+

{formatNumber(result.manual)} karung

+
+
+

IOT

+

+ {result.iot == null ? 'N/A' : `${formatNumber(result.iot)} karung`} +

+
+
+

Akurasi

+

{accuracyLabel}

+
+
+ {result.sync_error && ( +

+ Gagal menarik data IoT dari karung-web-admin: {result.sync_error} +

+ )} +
+ ); +}; + +export default InitialBalanceComparison; diff --git a/components/iotPanel/IotPanelChillFactorCard.tsx b/components/iotPanel/IotPanelChillFactorCard.tsx new file mode 100644 index 0000000..d15957e --- /dev/null +++ b/components/iotPanel/IotPanelChillFactorCard.tsx @@ -0,0 +1,131 @@ +import React from 'react'; +import { + CartesianGrid, + Line, + LineChart, + ReferenceDot, + ReferenceLine, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import { + CHICKEN_CHILL_FACTOR_POINTS, + chickenChillFactorFromAge, + formatChillFactor, +} from './chillFactor.ts'; + +const CHILL_FACTOR_BASE_MAX_DAY = + CHICKEN_CHILL_FACTOR_POINTS[CHICKEN_CHILL_FACTOR_POINTS.length - 1]!.age; + +export interface IotPanelChillFactorCardProps { + dayAge: number | null | undefined; + chillFactor: number | null | undefined; +} + +const IotPanelChillFactorCard: React.FC = ({ + dayAge, + chillFactor, +}) => { + const dayAgeValue = + dayAge != null && Number.isFinite(Number(dayAge)) ? Math.max(0, Number(dayAge)) : null; + const chartMinDay = CHICKEN_CHILL_FACTOR_POINTS[0]!.age; + const chartMaxDay = Math.max(CHILL_FACTOR_BASE_MAX_DAY, Math.ceil(dayAgeValue ?? 0)); + const chillFactorChartData = Array.from({ length: chartMaxDay - chartMinDay + 1 }, (_, idx) => { + const day = chartMinDay + idx; + return { day, factor: chickenChillFactorFromAge(day) ?? 0 }; + }); + const chillFactorXAxisTicks = Array.from(new Set([0, 7, 14, 21, 28, 35, 42, chartMaxDay])).filter( + (day) => day <= chartMaxDay + ); + const currentChillPoint = + dayAgeValue !== null && chillFactor != null && Number.isFinite(Number(chillFactor)) + ? { day: dayAgeValue, factor: Number(chillFactor) } + : null; + const chillFactorChartLabel = currentChillPoint + ? `Grafik chill factor. Umur ayam hari ${currentChillPoint.day}, chill factor ${formatChillFactor(currentChillPoint.factor)}.` + : 'Grafik chill factor belum tersedia karena umur ayam tidak tersedia.'; + + return ( +
+
+
+

Grafik Chill Factor

+

+ Grafik berdasarkan umur ayam untuk estimasi efek angin pada suhu terasa. +

+
+ + {formatChillFactor(chillFactor)} + +
+
+ + + + `${Number(value)}`} + stroke="#64748b" + fontSize={11} + label={{ + value: 'Umur (hari)', + position: 'insideBottom', + offset: -2, + fill: '#64748b', + fontSize: 11, + }} + /> + `${Number(value).toString().replace('.', ',')}`} + stroke="#64748b" + fontSize={11} + width={44} + /> + `Hari ${Number(day).toFixed(0)}`} + formatter={(value) => [formatChillFactor(Number(value)), 'Chill factor']} + /> + + {currentChillPoint && ( + <> + + + + )} + + +
+
+ ); +}; + +export default IotPanelChillFactorCard; diff --git a/components/iotPanel/IotPanelExperienceTempCard.tsx b/components/iotPanel/IotPanelExperienceTempCard.tsx new file mode 100644 index 0000000..733a698 --- /dev/null +++ b/components/iotPanel/IotPanelExperienceTempCard.tsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { formatNumber } from '../../utils/format.ts'; +import { formatChillFactor, type ExperienceCalc } from './chillFactor.ts'; + +const DEGREE_C = '\u00B0C'; + +const oneDecimal = (value: number | null): string => + value === null ? '--' : formatNumber(value, 1); + +const formatSigned = (value: number | null): string => { + if (value === null) return '--'; + const sign = value > 0 ? '+' : ''; + return `${sign}${oneDecimal(value)} ${DEGREE_C}`; +}; + +export interface IotPanelExperienceTempCardProps { + calc: ExperienceCalc; + apiExperienceTemp: number | null | undefined; +} + +const IotPanelExperienceTempCard: React.FC = ({ + calc, + apiExperienceTemp, +}) => { + const calculationRows = [ + { + label: 'Kecepatan angin', + value: calc.windSpeed === null ? '--' : `${oneDecimal(calc.windSpeed)} m/s`, + note: 'Dari sensor angin kandang', + }, + { + label: 'Chill factor', + value: formatChillFactor(calc.chillFactor), + note: 'Berdasarkan grafik chill factor', + }, + { + label: 'Koreksi RH', + value: formatSigned(calc.humidityAdjustment), + note: '(RH - 70) / 5', + }, + { + label: 'Suhu rata-rata', + value: calc.averageTemp === null ? '--' : `${oneDecimal(calc.averageTemp)} ${DEGREE_C}`, + note: 'Suhu rata-rata dari Panel', + }, + { + label: 'Chill effect', + value: formatSigned(calc.chillEffect), + note: '(Angin x chill factor) - koreksi RH', + }, + ]; + + const apiDiffers = + apiExperienceTemp != null && + calc.experienceTemp != null && + Math.abs(apiExperienceTemp - calc.experienceTemp) > 0.05; + + return ( +
+
+
+

+ + Experience Suhu +

+

Suhu yang dirasakan oleh ayam.

+
+

+ {calc.experienceTemp === null ? 'N/A' : `${oneDecimal(calc.experienceTemp)} ${DEGREE_C}`} +

+
+ +
+ {calculationRows.map((item) => ( +
+
+ {item.label} + {item.value} +
+

{item.note}

+
+ ))} +
+ +
+ Experience suhu = Suhu rata-rata - chill effect. + {apiDiffers && apiExperienceTemp != null && ( + + Nilai tercatat Panel: {oneDecimal(apiExperienceTemp)} {DEGREE_C}. + + )} +
+
+ ); +}; + +export default IotPanelExperienceTempCard; diff --git a/components/iotPanel/chillFactor.ts b/components/iotPanel/chillFactor.ts new file mode 100644 index 0000000..37f36af --- /dev/null +++ b/components/iotPanel/chillFactor.ts @@ -0,0 +1,79 @@ +export const CHICKEN_CHILL_FACTOR_POINTS = [ + { age: 0, factor: 8 }, + { age: 1, factor: 8 }, + { age: 7, factor: 7 }, + { age: 14, factor: 6 }, + { age: 21, factor: 4.5 }, + { age: 28, factor: 3.5 }, + { age: 35, factor: 3.5 }, + { age: 42, factor: 3 }, +] as const; + +export function chickenChillFactorFromAge(day: number | null | undefined): number | null { + const age = Number(day); + if (!Number.isFinite(age) || age < 0) return null; + + const firstPoint = CHICKEN_CHILL_FACTOR_POINTS[0]!; + if (age <= firstPoint.age) return firstPoint.factor; + + for (let idx = 1; idx < CHICKEN_CHILL_FACTOR_POINTS.length; idx += 1) { + const previousPoint = CHICKEN_CHILL_FACTOR_POINTS[idx - 1]!; + const nextPoint = CHICKEN_CHILL_FACTOR_POINTS[idx]!; + if (age > nextPoint.age) continue; + + const ageRange = nextPoint.age - previousPoint.age; + if (ageRange <= 0) return nextPoint.factor; + + const progress = (age - previousPoint.age) / ageRange; + return previousPoint.factor + (nextPoint.factor - previousPoint.factor) * progress; + } + + return CHICKEN_CHILL_FACTOR_POINTS[CHICKEN_CHILL_FACTOR_POINTS.length - 1]!.factor; +} + +export type ExperienceCalc = { + averageTemp: number | null; + windSpeed: number | null; + humidity: number | null; + humidityAdjustment: number | null; + chillFactor: number | null; + chillEffect: number | null; + experienceTemp: number | null; +}; + +export function computeExperienceCalc(args: { + averageTemp: number | null | undefined; + windSpeed: number | null | undefined; + humidity: number | null | undefined; + dayAge: number | null | undefined; +}): ExperienceCalc { + const toNumber = (value: number | null | undefined): number | null => + value != null && Number.isFinite(Number(value)) ? Number(value) : null; + + const averageTemp = toNumber(args.averageTemp); + const windSpeed = toNumber(args.windSpeed); + const humidity = toNumber(args.humidity); + const chillFactor = chickenChillFactorFromAge(args.dayAge); + const humidityAdjustment = humidity === null ? null : (humidity - 70) / 5; + const chillEffect = + windSpeed !== null && chillFactor !== null && humidityAdjustment !== null + ? windSpeed * chillFactor - humidityAdjustment + : null; + const experienceTemp = + averageTemp !== null && chillEffect !== null ? averageTemp - chillEffect : null; + + return { + averageTemp, + windSpeed, + humidity, + humidityAdjustment, + chillFactor, + chillEffect, + experienceTemp, + }; +} + +export function formatChillFactor(value: number | null | undefined): string { + if (value === null || value === undefined || !Number.isFinite(Number(value))) return '--'; + return Number(value).toFixed(3).replace('.', ',').replace(/0+$/, '').replace(/,$/, ''); +} diff --git a/components/sidebar/NavLink.tsx b/components/sidebar/NavLink.tsx new file mode 100644 index 0000000..6cf7347 --- /dev/null +++ b/components/sidebar/NavLink.tsx @@ -0,0 +1,130 @@ +import React, { useState, useEffect } from 'react'; +import { View } from '../../types/common.ts'; + +export interface NavItem { + view: View; + label: string; + icon: React.ReactNode; + permissionId?: string; + href?: string; + subItems?: NavItem[]; + disabled?: boolean; +} + +interface NavLinkProps { + item: NavItem; + isActive: boolean; + isCollapsed: boolean; + setView: (view: View) => void; + view: View; +} + +const NavLink: React.FC = ({ item, isActive, isCollapsed, setView, view }) => { + const [isOpen, setIsOpen] = useState(isActive); + + useEffect(() => { + if (isActive) { + setIsOpen(true); + } + }, [isActive]); + + useEffect(() => { + if (isCollapsed) { + setIsOpen(false); + } + }, [isCollapsed]); + + if (item.subItems) { + return ( +
  • + + {!isCollapsed && isOpen && ( +
      + {item.subItems.map((subItem) => ( +
    • + {subItem.href ? ( + +
      + {subItem.icon} +
      + + {subItem.label} + +
      + ) : ( + + )} +
    • + ))} +
    + )} +
  • + ); + } + + return ( +
  • + +
  • + ); +}; + +export default NavLink; diff --git a/components/ui/Feedback.tsx b/components/ui/Feedback.tsx new file mode 100644 index 0000000..d2683d7 --- /dev/null +++ b/components/ui/Feedback.tsx @@ -0,0 +1,55 @@ +import React from 'react'; + +type BannerProps = { + kind?: 'error' | 'info' | 'success'; + children: React.ReactNode; +}; + +const styles = { + error: 'bg-red-50 text-red-800 border-red-200', + info: 'bg-sky-50 text-sky-800 border-sky-200', + success: 'bg-green-50 text-green-800 border-green-200', +}; + +export const Banner: React.FC = ({ kind = 'info', children }) => ( +
    {children}
    +); + +export const PageHeader: React.FC<{ + title: string; + subtitle?: string; + icon?: React.ReactNode; + actions?: React.ReactNode; +}> = ({ title, subtitle, icon, actions }) => ( +
    +
    + {icon && ( +
    + {icon} +
    + )} +
    +

    {title}

    + {subtitle &&

    {subtitle}

    } +
    +
    + {actions} +
    +); + +export const Spinner: React.FC = () => ( +
    + + Memuat... +
    +); + +export const EmptyFarm: React.FC<{ onSettings: () => void }> = ({ onSettings }) => ( + + Pilih site, kandang, dan siklus di header. GM mendaftarkan site di{' '} + + ; BUH melihat rollup site dari GM yang dikelola. + +); diff --git a/components/weight/DailyDetailPanel.tsx b/components/weight/DailyDetailPanel.tsx new file mode 100644 index 0000000..146b44d --- /dev/null +++ b/components/weight/DailyDetailPanel.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import type { ChickenWeight } from '../../types/api.ts'; +import { formatDateId, formatNumber } from '../../utils/format.ts'; +import { formatWeight, getTargetWeightForAge } from '../../utils/weight.ts'; + +interface DailyDetailPanelProps { + row: ChickenWeight | null; + docWeight: number; +} + +const DetailCard: React.FC<{ + label: string; + value: string; + icon: React.ReactNode; + highlight?: boolean; +}> = ({ label, value, icon, highlight = false }) => ( +
    +
    +
    {icon}
    +
    +

    {label}

    +

    {value}

    +
    +
    +
    +); + +const DailyDetailPanel: React.FC = ({ row, docWeight }) => { + if (!row) { + return ( +
    +
    + +

    Belum ada data untuk tanggal ini

    +

    + Pilih tanggal lain untuk melihat rincian harian +

    +
    +
    + ); + } + + const target = getTargetWeightForAge(row.age, docWeight); + const deviation = target != null && row.average_weight > 0 ? row.average_weight - target : null; + + return ( +
    + ); +}; + +export default DailyDetailPanel; diff --git a/components/weight/DailyWeightGainChart.tsx b/components/weight/DailyWeightGainChart.tsx new file mode 100644 index 0000000..0b6612a --- /dev/null +++ b/components/weight/DailyWeightGainChart.tsx @@ -0,0 +1,193 @@ +import React, { useMemo } from 'react'; +import { + Bar, + CartesianGrid, + ComposedChart, + Legend, + Line, + ReferenceLine, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import type { ChickenWeight } from '../../types/api.ts'; +import { formatDateId } from '../../utils/format.ts'; +import { formatWeight, getTargetGainForAge } from '../../utils/weight.ts'; + +interface DailyWeightGainChartProps { + rows: ChickenWeight[]; + docWeight: number; +} + +type GainStatus = 'above' | 'near' | 'below' | 'none'; + +type ChartPoint = { + day: number; + date: string; + gain: number | null; + targetGain: number | null; + status: GainStatus; +}; + +const DailyWeightGainChart: React.FC = ({ rows, docWeight }) => { + const chartData = useMemo( + () => + [...rows].reverse().map((row) => { + const targetGain = getTargetGainForAge(row.age, docWeight); + const gain = row.average_daily_gain; + let status: GainStatus = 'none'; + if (gain != null && targetGain != null) { + const threshold = Math.abs(targetGain) * 0.1; + if (gain >= targetGain + threshold) status = 'above'; + else if (gain >= targetGain - threshold) status = 'near'; + else status = 'below'; + } + return { day: row.age, date: row.date, gain, targetGain, status }; + }), + [rows, docWeight] + ); + + const hasNoData = chartData.length === 0; + + const CustomLegend = () => ( +
    +
    +
    + Pertumbuhan Aktual +
    +
    +
    + Target Pertumbuhan +
    +
    + ); + + const CustomTooltip = ({ + active, + payload, + }: { + active?: boolean; + payload?: Array<{ payload: ChartPoint }>; + }) => { + if (!active || !payload?.length) return null; + const point = payload[0]?.payload; + if (!point || point.gain == null) return null; + const hasTarget = point.targetGain != null; + const gainDiff = hasTarget ? point.gain - point.targetGain! : null; + + return ( +
    +

    Hari ke-{point.day}

    +

    {formatDateId(point.date)}

    +
    +

    + Pertumbuhan Aktual:{' '} + {formatWeight(point.gain, { stripTrailingZeros: true })} +

    + {hasTarget ? ( + <> +

    + Target Pertumbuhan:{' '} + {formatWeight(point.targetGain!, { stripTrailingZeros: true })} +

    +

    + Selisih:{' '} + = 0 ? 'text-green-600' : 'text-orange-600'}> + {gainDiff! >= 0 ? '+' : ''} + {formatWeight(Math.abs(gainDiff!), { stripTrailingZeros: true })} + +

    +

    + Status:{' '} + + {point.status === 'above' + ? 'Di Atas Target' + : point.status === 'near' + ? 'Mendekati Target' + : 'Di Bawah Target'} + +

    + + ) : ( +

    + Target:{' '} + Belum ada data standar +

    + )} +
    +
    + ); + }; + + return ( +
    +
    +

    Grafik Kenaikan Berat Harian

    +
    +
    + {hasNoData ? ( +
    +
    +

    Tidak ada data tersedia

    +

    Data pertumbuhan belum tersedia

    +
    +
    + ) : ( + + + + + formatWeight(value, { stripTrailingZeros: true })} + /> + } /> + } /> + + + + + + + + )} +
    +
    + ); +}; + +export default DailyWeightGainChart; diff --git a/components/weight/DailyWeightProgressionChart.tsx b/components/weight/DailyWeightProgressionChart.tsx new file mode 100644 index 0000000..e132325 --- /dev/null +++ b/components/weight/DailyWeightProgressionChart.tsx @@ -0,0 +1,157 @@ +import React, { useMemo } from 'react'; +import { + CartesianGrid, + ComposedChart, + Line, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts'; +import type { ChickenWeight } from '../../types/api.ts'; +import { formatDateId } from '../../utils/format.ts'; +import { formatWeight, getTargetWeightForAge } from '../../utils/weight.ts'; + +interface DailyWeightProgressionChartProps { + rows: ChickenWeight[]; + docWeight: number; +} + +type ChartPoint = { + day: number; + date: string; + actual: number | null; + target: number | null; + chickenCount: number; +}; + +const DailyWeightProgressionChart: React.FC = ({ + rows, + docWeight, +}) => { + const chartData = useMemo( + () => + [...rows].reverse().map((row) => ({ + day: row.age, + date: row.date, + actual: row.average_weight, + target: getTargetWeightForAge(row.age, docWeight), + chickenCount: row.chicken_count, + })), + [rows, docWeight] + ); + + const hasNoData = chartData.length === 0; + + const CustomTooltip = ({ + active, + payload, + }: { + active?: boolean; + payload?: Array<{ payload: ChartPoint }>; + }) => { + if (!active || !payload?.length) return null; + const point = payload[0]?.payload; + if (!point || point.actual == null) return null; + const deviation = point.target != null ? point.actual - point.target : null; + + return ( +
    +

    Hari ke-{point.day}

    +

    {formatDateId(point.date)}

    +
    +

    + Aktual:{' '} + {formatWeight(point.actual, { stripTrailingZeros: true })} +

    +

    + Target:{' '} + {formatWeight(point.target, { stripTrailingZeros: true })} +

    + {point.chickenCount > 0 && ( +

    + Ayam: {point.chickenCount} ekor +

    + )} + {deviation != null && ( +

    + Deviasi:{' '} + = 0 ? 'text-green-600' : 'text-orange-600'}> + {deviation >= 0 ? '+' : ''} + {formatWeight(Math.abs(deviation), { stripTrailingZeros: true })} + +

    + )} +
    +
    + ); + }; + + return ( +
    +

    Grafik Berat Aktual vs Target

    +
    + {hasNoData ? ( +
    +
    +

    Tidak ada data tersedia

    +

    + Data berat belum tersedia untuk periode ini +

    +
    +
    + ) : ( + + + + + formatWeight(value, { stripTrailingZeros: true })} + /> + } /> + + + + + )} +
    + {!hasNoData && ( +
    +
    +
    + Berat Aktual +
    +
    +
    + Target Standar +
    +
    + )} +
    + ); +}; + +export default DailyWeightProgressionChart; diff --git a/components/weight/WeightStats.tsx b/components/weight/WeightStats.tsx new file mode 100644 index 0000000..160d83b --- /dev/null +++ b/components/weight/WeightStats.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import type { LatestAvg } from '../../types/api.ts'; +import { formatDateId, formatNumber } from '../../utils/format.ts'; +import { + adgStatus, + formatWeight, + getTargetWeightForAge, + type WeightStatus, + uniformityStatus, + weightDeviationStatus, +} from '../../utils/weight.ts'; + +const statusText: Record = { + ok: 'text-green-600', + warning: 'text-yellow-600', + critical: 'text-red-600', +}; + +const StatItem: React.FC<{ + icon: React.ReactNode; + label: string; + value: string; + status: WeightStatus; +}> = ({ icon, label, value, status }) => ( +
    +
    {icon}
    +
    +

    {label}

    +

    + {value} +

    +
    +
    +); + +interface WeightStatsProps { + latest: LatestAvg | null; + docWeight: number; +} + +const WeightStats: React.FC = ({ latest, docWeight }) => { + const target = latest ? getTargetWeightForAge(latest.age, docWeight) : null; + + return ( +
    +
    +

    Statistik Utama Pertumbuhan

    + {latest?.date ? ( +

    Data per: {formatDateId(latest.date)}

    + ) : null} +
    + {!latest ? ( +
    + +

    Data Tidak Tersedia

    +

    + Belum ada data timbangan untuk siklus ini. Data akan muncul setelah ayam ditimbang. +

    +
    + ) : ( +
    + } + label="Rata-rata Berat Ayam" + value={formatWeight(latest.average_weight, { stripTrailingZeros: true })} + status={weightDeviationStatus(latest.average_weight, target)} + /> + } + label="Pertambahan Bobot Harian (ADG)" + value={formatWeight(latest.average_daily_gain, { + suffix: '/hari', + decimals: 2, + truncate: true, + })} + status={adgStatus(latest.average_daily_gain)} + /> + } + label="Tingkat Keseragaman (Uniformity)" + value={`${formatNumber(latest.uniformity, 2, 2, true)} %`} + status={uniformityStatus(latest.uniformity)} + /> +
    + )} +
    + ); +}; + +export default WeightStats; diff --git a/context/AuthContext.tsx b/context/AuthContext.tsx new file mode 100644 index 0000000..d6d7bd0 --- /dev/null +++ b/context/AuthContext.tsx @@ -0,0 +1,88 @@ +import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { api, ApiError, AUTH_UNAUTHORIZED_EVENT } from '../services/apiClient.ts'; +import type { User } from '../types/api.ts'; + +type AuthContextValue = { + user: User | null; + loading: boolean; + login: (userName: string, password: string) => Promise; + logout: () => Promise; + refreshUser: () => Promise; +}; + +const AuthContext = createContext(null); + +export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const onUnauthorized = () => setUser(null); + window.addEventListener(AUTH_UNAUTHORIZED_EVENT, onUnauthorized); + return () => window.removeEventListener(AUTH_UNAUTHORIZED_EVENT, onUnauthorized); + }, []); + + useEffect(() => { + let cancelled = false; + (async () => { + try { + const me = await api.auth.me(); + if (!cancelled) setUser(me); + } catch (err) { + if ( + !cancelled && + !(err instanceof ApiError && (err.status === 401 || err.status === 403)) + ) { + console.error(err); + } + if (!cancelled) setUser(null); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, []); + + const login = useCallback(async (userName: string, password: string) => { + await api.auth.csrf(); + const next = await api.auth.login(userName, password); + setUser(next); + }, []); + + const logout = useCallback(async () => { + try { + await api.auth.logout(); + } finally { + setUser(null); + } + }, []); + + const refreshUser = useCallback(async () => { + try { + const me = await api.auth.me(); + setUser(me); + return me; + } catch (err) { + if (err instanceof ApiError && (err.status === 401 || err.status === 403)) { + setUser(null); + return null; + } + throw err; + } + }, []); + + const value = useMemo( + () => ({ user, loading, login, logout, refreshUser }), + [user, loading, login, logout, refreshUser] + ); + + return {children}; +}; + +export function useAuth(): AuthContextValue { + const ctx = useContext(AuthContext); + if (!ctx) throw new Error('useAuth must be used within AuthProvider'); + return ctx; +} diff --git a/context/FarmContext.tsx b/context/FarmContext.tsx new file mode 100644 index 0000000..32d4073 --- /dev/null +++ b/context/FarmContext.tsx @@ -0,0 +1,210 @@ +import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { api, errorMessage } from '../services/apiClient.ts'; +import type { Cycle, Flock, Kandang, Site } from '../types/api.ts'; +import { useAuth } from './AuthContext.tsx'; + +type FarmContextValue = { + sites: Site[]; + kandangs: Kandang[]; + flocks: Flock[]; + cycles: Cycle[]; + selectedSiteId: number | null; + selectedKandangId: number | null; + selectedCycleId: number | null; + selectedSite: Site | null; + selectedKandang: Kandang | null; + selectedCycle: Cycle | null; + loading: boolean; + error: string | null; + setSelectedSiteId: (id: number | null) => void; + setSelectedKandangId: (id: number | null) => void; + setSelectedCycleId: (id: number | null) => void; + reload: () => Promise; + updateCycle: (cycleId: number, patch: Partial) => void; +}; + +const FarmContext = createContext(null); + +export const FarmProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const { user } = useAuth(); + const [sites, setSites] = useState([]); + const [kandangs, setKandangs] = useState([]); + const [flocks, setFlocks] = useState([]); + const [cycles, setCycles] = useState([]); + const [selectedSiteId, setSelectedSiteId] = useState(null); + const [selectedKandangId, setSelectedKandangId] = useState(null); + const [selectedCycleId, setSelectedCycleId] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [reloadToken, setReloadToken] = useState(0); + + const reload = useCallback(async () => { + setReloadToken((token) => token + 1); + }, []); + + const updateCycle = useCallback((cycleId: number, patch: Partial) => { + setCycles((prev) => prev.map((c) => (c.id === cycleId ? { ...c, ...patch } : c))); + }, []); + + useEffect(() => { + if (!user) { + setSites([]); + setKandangs([]); + setFlocks([]); + setCycles([]); + return; + } + let cancelled = false; + (async () => { + setLoading(true); + setError(null); + try { + const nextSites = await api.sites.list(); + if (cancelled) return; + setSites(nextSites); + setSelectedSiteId((prev) => { + if (prev && nextSites.some((s) => s.id === prev)) return prev; + return nextSites[0]?.id ?? null; + }); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { + cancelled = true; + }; + }, [user, reloadToken]); + + useEffect(() => { + if (!user || selectedSiteId == null) { + setKandangs([]); + setSelectedKandangId(null); + return; + } + let cancelled = false; + (async () => { + try { + const next = await api.kandangs.list({ site_id: selectedSiteId }); + if (cancelled) return; + setKandangs(next); + setSelectedKandangId((prev) => { + if (prev && next.some((k) => k.id === prev)) return prev; + return next[0]?.id ?? null; + }); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } + })(); + return () => { + cancelled = true; + }; + }, [user, selectedSiteId, reloadToken]); + + useEffect(() => { + if (!user || selectedKandangId == null) { + setFlocks([]); + return; + } + let cancelled = false; + (async () => { + try { + const next = await api.flocks.list({ kandang_id: selectedKandangId }); + if (cancelled) return; + setFlocks(next); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } + })(); + return () => { + cancelled = true; + }; + }, [user, selectedKandangId, reloadToken]); + + useEffect(() => { + if (!user || selectedKandangId == null) { + setCycles([]); + setSelectedCycleId(null); + return; + } + let cancelled = false; + (async () => { + try { + const next = await api.cycles.list({ kandang_id: selectedKandangId }); + if (cancelled) return; + setCycles(next); + setSelectedCycleId((prev) => { + if (prev && next.some((c) => c.id === prev)) return prev; + const active = next.find((c) => c.status === 'active'); + if (active) return active.id; + return next[0]?.id ?? null; + }); + } catch (err) { + if (!cancelled) setError(errorMessage(err)); + } + })(); + return () => { + cancelled = true; + }; + }, [user, selectedKandangId, reloadToken]); + + const selectedSite = useMemo( + () => sites.find((s) => s.id === selectedSiteId) ?? null, + [sites, selectedSiteId] + ); + const selectedKandang = useMemo( + () => kandangs.find((k) => k.id === selectedKandangId) ?? null, + [kandangs, selectedKandangId] + ); + const selectedCycle = useMemo( + () => cycles.find((c) => c.id === selectedCycleId) ?? null, + [cycles, selectedCycleId] + ); + + const value = useMemo( + () => ({ + sites, + kandangs, + flocks, + cycles, + selectedSiteId, + selectedKandangId, + selectedCycleId, + selectedSite, + selectedKandang, + selectedCycle, + loading, + error, + setSelectedSiteId, + setSelectedKandangId, + setSelectedCycleId, + reload, + updateCycle, + }), + [ + sites, + kandangs, + flocks, + cycles, + selectedSiteId, + selectedKandangId, + selectedCycleId, + selectedSite, + selectedKandang, + selectedCycle, + loading, + error, + reload, + updateCycle, + ] + ); + + return {children}; +}; + +export function useFarm(): FarmContextValue { + const ctx = useContext(FarmContext); + if (!ctx) throw new Error('useFarm must be used within FarmProvider'); + return ctx; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..29b5608 --- /dev/null +++ b/index.html @@ -0,0 +1,158 @@ + + + + + + CP Dashboard Executive — Main Office + + + + + + +
    + + + + diff --git a/index.tsx b/index.tsx new file mode 100644 index 0000000..3029972 --- /dev/null +++ b/index.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App.tsx'; +import ErrorBoundary from './components/common/ErrorBoundary.tsx'; + +const rootElement = document.getElementById('root'); +if (!rootElement) { + throw new Error('Could not find root element to mount to'); +} + +ReactDOM.createRoot(rootElement).render( + + + + + +); diff --git a/mockData/cobbStandard.ts b/mockData/cobbStandard.ts new file mode 100644 index 0000000..1c9a930 --- /dev/null +++ b/mockData/cobbStandard.ts @@ -0,0 +1,44 @@ +export const cobbStandardPerformance = [ + { day: 1, dailyGainPercent: 0.33333, fcr: 0.232 }, + { day: 2, dailyGainPercent: 0.28571, fcr: 0.417 }, + { day: 3, dailyGainPercent: 0.23611, fcr: 0.573 }, + { day: 4, dailyGainPercent: 0.22472, fcr: 0.679 }, + { day: 5, dailyGainPercent: 0.20183, fcr: 0.773 }, + { day: 6, dailyGainPercent: 0.19847, fcr: 0.841 }, + { day: 7, dailyGainPercent: 0.17834, fcr: 0.902 }, + { day: 8, dailyGainPercent: 0.16216, fcr: 0.958 }, + { day: 9, dailyGainPercent: 0.14884, fcr: 1.012 }, + { day: 10, dailyGainPercent: 0.14575, fcr: 1.053 }, + { day: 11, dailyGainPercent: 0.13428, fcr: 1.097 }, + { day: 12, dailyGainPercent: 0.13396, fcr: 1.126 }, + { day: 13, dailyGainPercent: 0.13187, fcr: 1.15 }, + { day: 14, dailyGainPercent: 0.12864, fcr: 1.165 }, + { day: 15, dailyGainPercent: 0.12688, fcr: 1.177 }, + { day: 16, dailyGainPercent: 0.11832, fcr: 1.191 }, + { day: 17, dailyGainPercent: 0.11092, fcr: 1.206 }, + { day: 18, dailyGainPercent: 0.10445, fcr: 1.221 }, + { day: 19, dailyGainPercent: 0.09875, fcr: 1.235 }, + { day: 20, dailyGainPercent: 0.09494, fcr: 1.25 }, + { day: 21, dailyGainPercent: 0.09017, fcr: 1.264 }, + { day: 22, dailyGainPercent: 0.08484, fcr: 1.284 }, + { day: 23, dailyGainPercent: 0.07918, fcr: 1.303 }, + { day: 24, dailyGainPercent: 0.07428, fcr: 1.321 }, + { day: 25, dailyGainPercent: 0.06998, fcr: 1.337 }, + { day: 26, dailyGainPercent: 0.06619, fcr: 1.356 }, + { day: 27, dailyGainPercent: 0.06282, fcr: 1.373 }, + { day: 28, dailyGainPercent: 0.05981, fcr: 1.402 }, + { day: 29, dailyGainPercent: 0.0584, fcr: 1.423 }, + { day: 30, dailyGainPercent: 0.05704, fcr: 1.442 }, + { day: 31, dailyGainPercent: 0.05513, fcr: 1.46 }, + { day: 32, dailyGainPercent: 0.05336, fcr: 1.478 }, + { day: 33, dailyGainPercent: 0.05172, fcr: 1.496 }, + { day: 34, dailyGainPercent: 0.04967, fcr: 1.512 }, + { day: 35, dailyGainPercent: 0.04732, fcr: 1.53 }, + { day: 36, dailyGainPercent: 0.0446, fcr: 1.549 }, + { day: 37, dailyGainPercent: 0.0426, fcr: 1.568 }, + { day: 38, dailyGainPercent: 0.0403, fcr: 1.589 }, + { day: 39, dailyGainPercent: 0.0382, fcr: 1.61 }, + { day: 40, dailyGainPercent: 0.0365, fcr: 1.631 }, + { day: 41, dailyGainPercent: 0.0348, fcr: 1.653 }, + { day: 42, dailyGainPercent: 0.0337, fcr: 1.675 }, +]; diff --git a/mockData/weightStandardData.ts b/mockData/weightStandardData.ts new file mode 100644 index 0000000..6fae219 --- /dev/null +++ b/mockData/weightStandardData.ts @@ -0,0 +1,144 @@ +export const weightStandardData = { + headers: [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, + ], + data: [ + { + day: 35, + values: [ + 43, 62, 80, 102, 127, 152, 179, 211, 244, 286, 331, 374, 419, 475, 538, 595, 657, 724, 790, + 861, 938, 1036, 1113, 1193, 1275, 1359, 1449, 1543, 1655, 1746, 1839, 1936, 2032, 2132, + 2237, + ], + }, + { + day: 36, + values: [ + 44, 63, 82, 104, 130, 156, 183, 214, 248, 290, 336, 379, 426, 482, 545, 603, 665, 733, 800, + 872, 950, 1046, 1123, 1204, 1286, 1371, 1462, 1557, 1667, 1758, 1853, 1950, 2046, 2147, + 2253, + ], + }, + { + day: 37, + values: [ + 45, 65, 84, 106, 133, 159, 187, 217, 251, 294, 340, 385, 432, 489, 550, 609, 672, 741, 808, + 881, 960, 1054, 1132, 1213, 1296, 1382, 1473, 1569, 1676, 1768, 1863, 1961, 2058, 2159, + 2266, + ], + }, + { + day: 38, + values: [ + 46, 66, 85, 108, 135, 162, 190, 221, 256, 299, 346, 391, 439, 497, 556, 615, 679, 749, 817, + 890, 970, 1063, 1141, 1223, 1307, 1393, 1485, 1582, 1687, 1779, 1875, 1973, 2071, 2173, + 2280, + ], + }, + { + day: 39, + values: [ + 47, 67, 87, 110, 138, 165, 194, 224, 259, 304, 351, 397, 445, 504, 563, 623, 688, 758, 827, + 901, 982, 1071, 1151, 1233, 1318, 1405, 1498, 1595, 1697, 1790, 1886, 1986, 2083, 2186, + 2294, + ], + }, + { + day: 40, + values: [ + 48, 68, 89, 113, 140, 168, 198, 228, 264, 308, 356, 403, 452, 512, 569, 629, 695, 766, 835, + 911, 992, 1080, 1160, 1243, 1328, 1416, 1510, 1608, 1707, 1800, 1897, 1997, 2095, 2199, + 2307, + ], + }, + { + day: 41, + values: [ + 49, 70, 90, 115, 143, 172, 202, 232, 270, 313, 361, 408, 458, 519, 575, 636, 702, 773, 843, + 920, 1002, 1088, 1169, 1253, 1338, 1427, 1521, 1620, 1717, 1811, 1908, 2009, 2108, 2212, + 2321, + ], + }, + { + day: 42, + values: [ + 49, 71, 92, 117, 146, 175, 206, 236, 274, 317, 366, 414, 464, 526, 581, 643, 709, 782, 853, + 930, 1013, 1097, 1178, 1263, 1349, 1438, 1533, 1633, 1727, 1821, 1919, 2020, 2120, 2224, + 2334, + ], + }, + { + day: 43, + values: [ + 50, 72, 94, 119, 148, 178, 209, 243, 281, 322, 371, 419, 471, 533, 587, 649, 716, 790, 861, + 939, 1023, 1105, 1187, 1272, 1359, 1449, 1545, 1645, 1736, 1831, 1930, 2031, 2132, 2237, + 2347, + ], + }, + { + day: 44, + values: [ + 62, 81, 102, 125, 151, 181, 213, 247, 285, 328, 376, 425, 477, 540, 590, 652, 722, 796, 868, + 945, 1032, 1100, 1182, 1267, 1354, 1443, 1549, 1657, 1720, 1815, 1913, 2015, 2115, 2248, + 2360, + ], + }, + { + day: 45, + values: [ + 52, 75, 97, 123, 154, 184, 217, 249, 288, 330, 381, 430, 483, 547, 598, 661, 730, 804, 877, + 957, 1042, 1120, 1203, 1290, 1378, 1469, 1566, 1668, 1755, 1851, 1950, 2053, 2154, 2261, + 2372, + ], + }, + { + day: 46, + values: [ + 53, 76, 99, 125, 157, 188, 221, 253, 292, 334, 386, 436, 489, 554, 604, 668, 738, 813, 887, + 967, 1054, 1130, 1214, 1301, 1390, 1482, 1580, 1682, 1766, 1863, 1963, 2066, 2168, 2275, + 2387, + ], + }, + { + day: 47, + values: [ + 54, 78, 101, 128, 159, 191, 224, 256, 296, 339, 391, 441, 495, 561, 610, 675, 745, 821, 896, + 977, 1064, 1138, 1223, 1311, 1400, 1493, 1591, 1695, 1776, 1873, 1974, 2078, 2180, 2288, + 2401, + ], + }, + { + day: 48, + values: [ + 55, 79, 102, 130, 162, 194, 228, 259, 299, 343, 395, 447, 502, 568, 616, 682, 752, 829, 904, + 986, 1074, 1147, 1232, 1320, 1411, 1504, 1603, 1707, 1784, 1884, 1985, 2090, 2193, 2301, + 2414, + ], + }, + { + day: 49, + values: [ + 56, 80, 104, 132, 165, 197, 232, 262, 303, 347, 400, 452, 508, 575, 622, 688, 760, 837, 913, + 996, 1085, 1155, 1241, 1330, 1421, 1515, 1615, 1720, 1796, 1894, 1996, 2101, 2205, 2314, + 2428, + ], + }, + { + day: 50, + values: [ + 57, 81, 106, 134, 167, 200, 236, 265, 307, 351, 405, 458, 514, 582, 628, 695, 767, 845, 922, + 1005, 1095, 1164, 1250, 1340, 1431, 1526, 1627, 1732, 1790, 1894, 1996, 2101, 2205, 2314, + 2428, + ], + }, + { + day: 51, + values: [ + 57, 81, 106, 134, 167, 200, 206, 265, 307, 351, 405, 458, 514, 582, 628, 695, 767, 845, 922, + 1005, 1095, 1164, 1250, 1340, 1431, 1526, 1627, 1732, 1806, 1905, 2007, 2113, 2217, 2326, + 2441, + ], + }, + ], +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ff7186d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8320 @@ +{ + "name": "dashboard-cpsp-executive", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "dashboard-cpsp-executive", + "version": "0.1.0", + "dependencies": { + "exceljs": "^4.4.0", + "html2canvas": "^1.4.1", + "jspdf": "^4.2.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "recharts": "^3.1.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@types/node": "^26.2.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@typescript-eslint/eslint-plugin": "^8.67.0", + "@typescript-eslint/parser": "^8.67.0", + "@vitejs/plugin-react": "^5.0.0", + "eslint": "^8.57.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.6", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "husky": "^9.1.7", + "jsdom": "^29.0.2", + "lint-staged": "^17.3.0", + "prettier": "^3.9.6", + "typescript": "~5.8.2", + "vite": "^6.2.0", + "vitest": "^4.1.5" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", + "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.1.tgz", + "integrity": "sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.3.0.tgz", + "integrity": "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.0.tgz", + "integrity": "sha512-5+5LEmFuY1AjXdYhmgjTJogtQnP1evJ1zrBZGUNZ0thkpwnnmKxcHdAMn/OtFjAb25zA+jKDVYVRl+5G7rjv1A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.1", + "@csstools/css-calc": "^3.3.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.8.tgz", + "integrity": "sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "license": "MIT", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "license": "MIT" + }, + "node_modules/@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "license": "MIT", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/@fast-csv/parse/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "license": "MIT" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", + "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/pako": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.4.tgz", + "integrity": "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==", + "license": "MIT" + }, + "node_modules/@types/raf": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz", + "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/react": { + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.67.0.tgz", + "integrity": "sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/type-utils": "8.67.0", + "@typescript-eslint/utils": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.67.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.67.0.tgz", + "integrity": "sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz", + "integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.67.0", + "@typescript-eslint/types": "^8.67.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.67.0.tgz", + "integrity": "sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz", + "integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.67.0.tgz", + "integrity": "sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/utils": "8.67.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz", + "integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz", + "integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.67.0", + "@typescript-eslint/tsconfig-utils": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.67.0.tgz", + "integrity": "sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz", + "integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.67.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.15", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz", + "integrity": "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "license": "MIT", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canvg": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.11.tgz", + "integrity": "sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@types/raf": "^3.4.0", + "core-js": "^3.8.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^6.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "license": "MIT/X11", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.50.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz", + "integrity": "sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.23", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz", + "integrity": "sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/dompurify": { + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", + "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optional": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.409", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.409.tgz", + "integrity": "sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz", + "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-toolkit": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.51.0.tgz", + "integrity": "sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks", + "tests/types", + "tests/browser-compat" + ] + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.6.tgz", + "integrity": "sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.1", + "synckit": "^0.11.13" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/exceljs": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", + "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==", + "license": "MIT", + "dependencies": { + "archiver": "^5.0.0", + "dayjs": "^1.8.34", + "fast-csv": "^4.3.1", + "jszip": "^3.10.1", + "readable-stream": "^3.6.0", + "saxes": "^5.0.1", + "tmp": "^0.2.0", + "unzipper": "^0.10.11", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "license": "MIT", + "dependencies": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-png": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/fast-png/-/fast-png-6.4.0.tgz", + "integrity": "sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==", + "license": "MIT", + "dependencies": { + "@types/pako": "^2.0.3", + "iobuffer": "^5.3.2", + "pako": "^2.1.0" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fflate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/immer": { + "version": "11.1.17", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.17.tgz", + "integrity": "sha512-8Vu44Y0MuMBlTQz/jQ8HEMYNq/bBqk87MnBwYR5mC8AthfhEXidZ5aT/oA/CUqboa8THKltnD9L3xyqhU/Sy1Q==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/iobuffer": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz", + "integrity": "sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==", + "license": "MIT" + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", + "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.1.11", + "@asamuzakjp/dom-selector": "^7.1.1", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", + "@exodus/bytes": "^1.15.0", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.3.5", + "parse5": "^8.0.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.1", + "undici": "^7.25.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.1", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/jsdom/node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jspdf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-4.2.1.tgz", + "integrity": "sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.6", + "fast-png": "^6.2.0", + "fflate": "^0.8.1" + }, + "optionalDependencies": { + "canvg": "^3.0.11", + "core-js": "^3.6.0", + "dompurify": "^3.3.1", + "html2canvas": "^1.0.0-rc.5" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lint-staged": { + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.3.0.tgz", + "integrity": "sha512-woZS3vNe3UKqBaLPvbLOtKRY4tLANpWQhom12MGWqC8Mh1lCOO+WgSwmX2amjJAqTY9BkXYW87fCUH5H9Ph6xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^4.0.5", + "string-argv": "^0.3.2", + "tinyexec": "^1.2.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=22.22.1" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + }, + "optionalDependencies": { + "yaml": "^2.9.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", + "license": "ISC" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "license": "MIT" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "license": "MIT" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "license": "MIT" + }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-exports-info": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", + "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.2.0.tgz", + "integrity": "sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT", + "optional": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "optional": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/react-is": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", + "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", + "license": "MIT", + "peer": true + }, + "node_modules/react-redux": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", + "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/recharts": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.10.1.tgz", + "integrity": "sha512-QXFrvt6IVcw7eeZCoyXTwkIJAX3Dv1nyVhMicXJ47GsGDDpcN8z6o644DibE9XjpBTThtsomLKnTV6lc+cVFUA==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "^1.9.0 || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^11.1.8", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.2.0", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT", + "optional": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reselect": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", + "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "license": "MIT OR SEE LICENSE IN FEEL-FREE.md", + "optional": true, + "engines": { + "node": ">= 0.8.15" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stackblur-canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", + "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/synckit": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.3.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.10.tgz", + "integrity": "sha512-GgouD1B+sWwvkaEq8vXC15DjQitxbvs12oIXELpconwm+Tg3zfcEv4jgzq3vtKverDXsg3VI8aRgNL2Nra0Iog==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.10" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.10.tgz", + "integrity": "sha512-KnQjp53ZekKgm/r3l+u8kJGGzYgrWdP8+Mql7a4vijh2WE0IrZWspQj/TpTxDho/YxO+AnOZnIjQcCD+q6iJsw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "license": "MIT/X11", + "engines": { + "node": "*" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", + "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unzipper": { + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", + "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", + "license": "MIT", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/uuid": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "license": "MIT", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f07ce30 --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "dashboard-cpsp-executive", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "lint": "eslint . --ext .ts,.tsx", + "lint:fix": "eslint . --ext .ts,.tsx --fix", + "format": "prettier --write \"**/*.{ts,tsx,json,md}\"", + "type-check": "tsc --noEmit", + "test": "vitest", + "test:run": "vitest run" + }, + "lint-staged": { + "*.{ts,tsx}": [ + "eslint --fix", + "prettier --write" + ], + "*.{json,md}": [ + "prettier --write" + ] + }, + "overrides": { + "uuid": "^11.1.1", + "tmp": "^0.2.6" + }, + "dependencies": { + "exceljs": "^4.4.0", + "html2canvas": "^1.4.1", + "jspdf": "^4.2.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "recharts": "^3.1.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@types/node": "^26.2.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@typescript-eslint/eslint-plugin": "^8.67.0", + "@typescript-eslint/parser": "^8.67.0", + "@vitejs/plugin-react": "^5.0.0", + "eslint": "^8.57.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.6", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "husky": "^9.1.7", + "jsdom": "^29.0.2", + "lint-staged": "^17.3.0", + "prettier": "^3.9.6", + "typescript": "~5.8.2", + "vite": "^6.2.0", + "vitest": "^4.1.5" + } +} diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..286f0fd47f870ac66396092c526f62a277013280 GIT binary patch literal 107806 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 z zS~DGHf30~_ryclZL)RnX@_HWHK~M#V0gL{}ggK%+7=n!wzJ3l^G;o$OrM_JujuR3i z$ph~dxeuzz7jSsS4jYvEIwhqkj#}SIT)O&YkKcfNV(l61lzEFQ7qI=eRX(&p zg6{|3!>=Re|Mb3e%~aE!#Gd~?f>M9J`pT9xQP(|O(V&cO<+WZzh~R3~jP4N`UXa_a zKcwyKu+*qEwf{Em0Dd-cG$AL!>LvdeBmWL%x$eAq)mh1I{onhSKiK>1OAr;2EB#v& z&vUg#->lFx?c5erY=&vdbo1v+iIk42Zw{hTiyb!tqXM5NmpQ6t9qwx0Gg139>FV3? zdvXP}@3|fN?*~6ul~sb3iJ8~jtm<*ypxS%Uc4Kk%uT+ai(9~rhRcUr@batWoBlT5| z%wYV1K7J5d9OExD6SB`o1`nqAG&%;g0P>OV_RBDAdZ>vC&3&e--s#I9*Lva>v3&U( z{<+o9viUdF#5f-W*mKv4qEkCBOGL6qZ|tZwVW>*kTJG0ttySmEj&IMq8!Gm>>a82P z(xxQ#aBfXmdc>jJ+g6rDBG6g(O3ycqQZM~~a^oIR<}I(Bc&bJmHfMZCZ|B92HQv?!a*;-I zHT>MuBARDY`p_v+BITUPLhzw*H2vBWuK{!NjwQgFIM9SSZ}BSl9?77?IlhpOqF9Na zC|qV_{e^gC^9)}f-qtfAwa>Qf`KgX%Mrq1=sb$jL8e}%S6RHkT64j)~o&kmo6J@rq-1Uv-Iec@v#+`V+S zm_2N0_dUKec-YTM-|87gkNL6SYR3Y@wRZz!I|$9lTdNeG)KodYFVXQH_v)uIbM%%+ zP|xP96D~eT^>>i1Udebjx|KmT=9k?!iDG+ezOtaAE&*;X=_G7)Mkkauo zLZo)fS-tDo&!KaeL1{BduQ)Xl!mw!8(xJ0+s>N9Kaz*Xy<>T7^uJu+oy#Cy4d0>$w zAFvSlN#x;Vnm$LMJ$vI{Jdh6ne}Joz3$YtI*JT-<%xlU9?(O6He6msmGxTw&s}UBZ zXoxu-aoF{qIOJ{%>t@;0j#b{6JgXNVUNAf1+;d&7=h+twXUa|m629Cv)4e=g%P5m~ zEF)YTO7MA#k3)HSFUi{aGPAumzp_`BA2#oJ43fvGgg908?(pG6B*Iur-b=N)3+jH! zFvP3*w-P{K2P7C5d0nwdml@Xm=5)Ge6Hy)3yB>Cv*pg+?!|ufxVYC~S zn@1=gZWgyO4L}G0H{(Kpx)`Px!Sl#n}1FeDJb$9!II4>t1RM; zvd=?r#df^(s~+CUh@n$E^9OI1)Qr5tR#;Nn^0vaZU;Ad7H}6(3Ljb&!19SL0U~DHB zX_8Gp7t`cf6GXL0DnY~Xzr-W-ghx3f5oNh_K|Ul#Z&YuY4xm6jeJIx~EJ}`0?8TQ8)1~ssYmkub(gL|TPRId!t0KS>fEH+tg_GIR2U z2mFzsIT`(_mdR3yarJg{gW1wo*4V_z$c2BADJY1w9j&N?+g=Kdq9Lk}m2IP^Itx*g z#eovt;||nR`yf7#A9j2+okt+{>%QQD8d2k+q54aUatZ1zbCH7o}4)8&9tNAmasBxuy zBH4hwkPSpB@Wx~*iimscDHY{&P|<>#x}=tDDRws)VETXum?JMs`lOp~gbmTP<( zkTGBV@lS%gKvWpk>mg0NMqT)EsB4rX+L0#JNMjUzp$h*9ZcIEGJbVZX@d0;k-RGrj z)KC+%^9R}8>8XH|65W&nIcw;=3`S--xmqjLPJPtAV?(~(g%}h>-XBk>?_`M(J{%&% zqEZkY+Rj_|C(pQaswhxr-JHHXmhcmWJze!9_x|6$b`mD6a;bTUbH$?!FY{=RmKOVh z>DCw6{%ZmMG}YeUZ|?Xwq%Vo9Ntt*GGKFry#VOX!A1pf+59ciBy~$sLL6;2eIo00f zT_5&ig9Y!g_?1lb1xm=de32jioy4+^n4^T|QbxyIiSrF6tI3R)L#Tz1jpmXeq4#lN zabIV*NT(sUr5A?Fie}1OUbZa{S_OWlDG>^M4J2=w9#rrsG{&1KME|x}@hL2Hj91={ zWgP?%?DqamSd?>9uvx&RmEvpMBWv3L*|;pHZeDB)rLKMpn749^F^KBH?1vZmKmHU~ zZE^T0^*69T`x}V4vnHv%zg>y#2^GfOnA&9vAphK2lQtibasEMaz?HBM+F**fdSzt3 zG>Gqc4Oa=StLSf3o1E#ER0%DKwOcyKT_@oC__M<0r_kJphbya&Ag%HoxW2wH-S=yc zW7t+2jZCOMF5jk)QC&8MJ?rVIGN>_MKGzh6QgQuvGabYnQ->&Z{UzSPSfNZ{G$4{x z-qY{?b0#RR>8n_4GwP0GPYm#1KaMYNd>Y!Jce!siZ(#;{x_|Ll?!6~7cYj{J%vSKQo zYlHPrI>bxzhzqxfQJz&WStfsobuOIs=JRlh7>B1$m!-J4d(Yj|v6_n+ zivO~Ee-bzcCd;j2ZhRqZTkx)v4u_u< zwHvd7y|l1Y=I_h5>iUG>kRc1I9P;^W5^0xkL>9xJv z7R@sNKlfK?)WzjF^w>$hbzPL@kjIdhL2kqL-Tls&NrKg1%OfOK+`1OMPU_X;>83q@ z%Fq&<>9JjeZXgd7-3_(2^fZ~8y9`GuC)66EdZ$vQ11G;R;*8-=QDT&42Cux-f7wcY zF5_2Q&z+RCe1EbCMersfT{nPdR`oKaL#^j=rXKNPNT|l+aeMZC(0OA(Tv%(Xoi^-) zN6ru$I`VU&UbX7R5s4e0M1-mEa;$0OF`T`uL9dev5aTl;fylQW7%KH zy2Q_4)5ibBj4$=CYqxvluGDsZt`6S81`qfZy2MdPa(=a%@6=?g;fY>w0w({gaiTt6 zS#xWIF+Vzs|Gn`BJ8ZS9y(b3tb8Y{zPsgqopigv^#Eh4c?|9J;y2L$gmOtlU?AvV6 z@U-EnRrs^Po0a7+=8tosAn+C7c0Z%#B+Qak*^{s!C|r>r-5m~p-8Z?Et@h34huZ?t zZNpSWx{F@2p~|M?x7*io7z-rC%#os)rPx6{^3aoq%H7Jk?pye*D3>8O@>Xi8F|`eE zen%d~Gxph^KpKKcEG8(oZtf3wF!#3>>GLNq1>gOSmjNHm?cUhsCm=b3UP}@*R_~Jg zF=opZ=rffg@O6&)x9ZXnwNZ%~>p%Ag;w1opGl37d;hdbsWLP3^44p9KDuRu6nyu^i z{jF%b3PJ+#BUv9|xtBY0U1qCp`{Kkv;N3qDqWS+C$;B@MnkE+1c2)0eU9Qz}pkWI{ zo$%`dw;UxrJRYX6?bGbY(j_b0kSl7!CRN7K`HJU+8=Lzd62VVSf?yQ0y2@7Nz}!46 z`P>o)nRnTPK?SP4!I_MCWVt<|ILMRC{Ok^l5>Q?uttSO?9;!E(FA54+VjN|h4C;8d zS)+wfG19l-?HDV~5>(r-x&JveM@0LgSCHoFWs0}XsahSbcv*i!#bcO#)O*$EMT&c~ zF20oWInXJt7|3nEh3!7$_l6QU_57itKl1Q^j2lM4p(}BMHC$P_;&QOpRFXdq`XMM* z?p-ekHVyDhW&9BU&zg)o+26fz@<>kUP1_G=)E$FPnC?}QqDDbfHMI4U%Ez*9IRW%7 zts8_a)C&f|F|#+_8t7pz-hi1)d`~osWv|C!n_S!!Fa zl^`@*mD%2ykQz6MA1svS3vX$yVHGOx>iyL-- zA@qy_@6cCie3w7`b@{efF6{V<0@a73Qm8B8VzpveJu>2bQqWVxvj0(ZwlMZCuDPq= z$eNG&m872Pd3LVlJ`Fg@)UIb3Zc$m)4Q$hnO7${`N+Z~X{vy;{zwh?Puz-9v6qI|F z!>Y>_jGB9)sSstIuBQ@aNlz!0mjrR27&qfWs=N~09m^C@tPzX6%_=|Uhmwk3=$LhzBo8U?ZzClc zIF~Nm&UjPx{?uFJ7EPVTiv_N#-v2)Of?yR)X+@pw`e(2NKVqc%si{`z%$e-*Q`8yg$%iZj)jN6*LVfk9bU+&uG_~pado_Bj z${^ki@D7LX1m5z-)SQKNjgf3z390GomxhN$1|{rXaaMnR)$Yftt{!CX>Jt27WF09g zFN@3^mk%et0!HpmzU>df{E!_|A6Ou9z-xZNGpk2u%R?i8zx`|0M0J*e9CNUm36sx@ zsL#VG!T_Et#Eig!xib%)TAg4S_=nQ*g|Em(87rT!65CX3Ww4W0{@ZpWNvA8BK6%<+4(TM&U zc@M;(b=LT}T97kf+ZtoE*CAonsTca6S5pz=d|zepYj^7?_j0;d>VJD$Yjr4AABEM) z?JXEZUSJbAqWjjFg&~mAVHjewQ2p%P_!dP=DWTuQ7l_K$q5)s1HF|g~PT07@ggi0O zL$=3<3KYdUFV&_UV6^f>Vh)o_yZa>(w}TYRd?dskXSWmtjxjYe{lT2$8WHs?v9_VD zG*gt<#v1PBc3IgDY~n1RxGv<}#bQ998Zx zzdAx7TS=*~KK~39&K04U-m;54u%$VZ;XDeW;$rJgxrD}OeP*b2!bftN>L6yHSyJ<+ zR}B|}_OD~GC!J-bfEWcL{(9+-*;TNc-#M_MT0RQVyZYc$H;uAdIUL5jYC%pQi-3}C z8o}GGEPQE>D1^T~nx839Xl#&ZN_be8xKj+^p*d0I+m(ZtWD&yYT>4Y&U#$jWkyiNE zOU34XB}3Dt+poWRu+bhPB>~Rnf$QkE=HRVFmSDvJ*1@vCqZLnX^cI&Loa@Jx1zGLt zj%D6s*uAXp_X8Os#L_MAk=g6-64Wpt?F%WJfvmJZUUWvgmm< zDU=$CtZ3vn5KkY0sd0TGYfasCyi^*c$}=3&XdEFz3aA`wmvE;H(0BeAF{%aX`W{V? z52JPs`I0fByAyo*K1;G+1MB;q(W_4ONB+)=EuISkj}t&kg;ojudfZt_-KjGvBd5Gn zBNU_5A5F?b&SX#2QYIX(oX2`SbWrr@d1NEJ3m!xDRA=w%?09sBS5#Y!`6#Uq3n~L; zx-S8AN(+|9$@8Q{a91r;S3A*@h!0IlT-r8l2%GU8FhAZ$_i#0K)Qa#;bFD{VS8t^)O4+?Y?Ou-R z6mjfxz?8=NWxAu!#}Nxo=^THs2;`qMuMH@4UVzKs@te3IohNaoNl(R8xDKf8iu)GO zc@ZwXkZ?iec;xH68e)mRU$A<*4Xi;}Zdv(J!4`An^TPQLtiID>gAKdVUcjB(X%Z0Z zr1*>`!{2?uKAsN*CY#!pBCif$?^kg$P6V-tD;r?o;>-pRM!iS z>l+32erJrp5Lep$*HTiO{BOiH>5eVzNMbCv3wpYU5!&^&KvB!X$K9ueK`=^fu>3U` z_y5@Y%D0nYS2#-(6~Dv&d2vszD}w) zbo6FwqqX`<4YoZ`G(erLKuyQ{W+HLvQj9<@)IL26Xa4{nimb)o>DONPPB@#R6Qr5; zjqzK>j=Kt>HA4!+yiJ+`B`m(z$F{rZZ)+ zt?5y9AsoD%_sYi$XbAcUAR;Q57|ua4KGeYkB+3`iu>WW*Xs3LF`${?6`k=ts+Xv2I zuN37{N)-3tr0(pY0H0|Q@Pam=+ePcVovPTKuHHncPKea{T@73*eNCfBjqH%8a-r{*o=xw8r%kwpenRj?w4&mhn(7 z^A8>0zuo&o6<#L=uxZcYcR!;xpT}+UYZF+3xMVuzv@vOeESxmPqifGT?(Lh7cKwx= z+oNwuC3Nu!=mElwAZ@B|mfQ>&vm`FKZNDEt(_^fyj!=;yZuza1oaij5J!NG z7o1QS1K<^$zzA7xV0mNhSJ_JerJ0aKs>_f~t( zk$zj|lwTj(d8v1)WQuVT+de2NZtD0M12BLGEb(5@-4MmrH zOJF0aj^tzb0X(GHGQcngn82zza*XYzstONXWZSlD$Tl2!_@x90Z~$fjEm|VNZJF$1 zDBm34{x1?CzuzhWZOGUqQl5Gd_kLtuQfGv=5VX3 zckbNCcP1H?>rCF=_FWmUI7CudZmU?SgzofF6Cw7!ds~)}Gx5EI6HB6A4TQW7t=a*j zz`Ta?#=rmVdNby-6-#Lb5h{PD@#_*Mky0`TOo*`M1$%1C-Sf^kZ5fHPmc+<11QcHv zvm0EMvjuVgV_@FvW6{>HG+%8>`(k{;p0s}F&j|(Q2w%Uv=ahXPXWuDxbFq|inRvTB zl-K!>Q!&h_&Ac-L=zkXdkNuPv^h=$GnOC_#u`SA+XT0NFlEZL}I8J0KaQ8a3&Gt?V zNx6;m8e#w=X9^4u5KC5#PHAo1M7i)RYH^ph3EdikJ9oZP1?HBgaL$l3@blnl9nt;~ zuhamF9A3I_5fUZ3Xw%$Yivv{Np9gV;Qv#HXM`vOy^j9n=UoNs+UdHIrmJ=_{0|O|) z;*SmN<8?U**~b9KF}&K{XXv@DHT9G~b2Za(@TpRIuiwT*w@Yp+g(@vBbKsWPJ(fHZ?J)c=B=rS7_;UI%y%h4>&Y8ly(6LWCi!;NS@re+(J6;B~7z%iu@$Z`lkN*luak3k{0X&^pBsbli@mfzn$}4LjLIeV5nwAN)f2ot$8Aon}p3LPL|rKT^*EEwv^7b9kJ*y&{gI@h*io z_vigt$xJ?;sKT&wU0r9}U zg$)pFRPHfJWPJZu18nNi-Y78Gbh}Mx$9+TT0zJ23!JDMl@n+t;7k694yMUf5Hr z&_4Y(zOxl9o-dRYk(1_oqyNd}otFa!S?q5tJ+gtx@u-r9B|49~?G?=2|4!MZ2W;Cg zSw+?qZ&)5q*kxPlxs(fZ<^Ee-@l!F3#i|-WRm-A5*Y~wkQJbX1|30&$0|ZVHm4BUo zd)p45!&`$!wdva>f!T$B%MMab+iAb{W`hjh*jweRWO+loUUCtQH1U9Cq=hq zPpU84Ma)p;a^H6Ud~Y}v{2v!Te6MLasL+<5GOEb?`RyJj)#skchkClZW9?Fy#&>!L zCfmFzH+$LJjf3Hfv{Mw@?jFhT#lLO6GTPaOuYIZ@|NZ#?|NH+r@c%3ah5=uOTfR6+ zGUaC9*rI?@HmSNUz5bS?$E)irCH|E`hx%I3sjEj3 zjoCSjL+I>uW2R>Nu}7&$lj)^issrr_Q9~*XFv`8CBf94ld$sl6<*ROa^xFIst-W)^ zh=z*}56!Y^vjW}E%l>Mv|6oI@K+19@N{2*1ov1v^EONOvvy^+P(VnA0e$8tmm?)4J zc+^QQqx!j1i_4nVu0+ami{Et+`WNVRsfAK9kxJ6#|`8O*xI5E;nmN7i1G`jJSAt!I1tyc_Qw)3F6!L(kprE>qjJ9T2hH7r#F0G-H2&QSnNvv(Sts|A zjL=+Z;$G5=m=hKx?Q{t=PJge~l!fo}5zn*$l&vPSW1%gh#y){?8v>Gu^)TqGW3UJ) z&r^F%n`6ms<6)sA<+ti8Ob6`x$JH)W8Ns<{=arcLm1A_w<>%6d#OL4My>5($-xn-qQ1BqmZUyURrtgaM-^DIWuV4!^-y4qbOwUd>Szzlg<$dDcf zDiDFftt8GSt)|R%INryQ58#o#K~ZTn%y#ODVo!a-=&C}AKB4SMFEJT4ot+$TnX3Mi zxZ(bbr!~kw9W{n!z5Y;&qdZmUwD0p9WS`hT%r~hW;Wf4w5!L}iF_@UMgYpNWf;x_p zUQL+RzU^5KU9E-D?V1iv&hS90y`gW%8v*w;=T;b8lulSZSaTRpEc@!)R?K+OLcJuX zptLXuhJDwgVD#XKch^hx`-@qoKXlNYE2Xx|^`FB!Ks_lei< z7vZAQ(?C|spmEPvXYPo5SN5+<(Z#7&vseG}d&aoCKQ7c$W}9{SJXP65<^P_Rc{6@9 z{pC|@yF(|JR?Gky?XM!cZeFYkjG6-P{hj`$%tkgm^mxNoQEk&Sht+?X^Now9kDTgh zAX)0e+@Zgtcn7wj>{hAjTptyG^~%)*sa+chJ)HkDc0c_s#N|m7)BMx(0!}mfWtKV{ zD3|59q-VZ+VFbm?^*_G%(-T0FoSS^6tSr;kRu}pZUP3$3iVwpXza*2#Pp#y_`p+*^ zl+EfonE4D}rEZ;N4fio5_&+`i8~zv)lt?|Yuc6GCXh3qoSQE5&M1Cy01MB$IuyPsJ z7(naL!vWk?)Cm;?`FaRG3GtPZFz*kg5PJnaQh!{yxh8cZ3*qHG3|3Bkk)R=bAW$dy z+2>Soc%q5K?B}u0&Le;NqqX@jLe`ikY6mOlD&L=9iJ^@cf5O2|z7o^Z^9Dxxv;)yi zY2P9*L#~qIA|bun#bSfeNlFGnwG39`y}sb}w*|S3Kd-Ljp=#{D8Om!XYd@~(_9hOl z>5?Us?QH*^AGk?(DqJl~Ds57kaU6%%_Fb0G2C*Qkhu%lE^)E`T_v9!)Ng3CkdeF!J zy1&iNWV9t__~Phyr!{(7>9}*_Ph`ys&|_-G>W!hmY|usL2D$BZmJE(|H$5Ef;eFG2 z;XxvpW!u#GOH|f7#KcG zObCq|50WE(-MUn`I>S}<)bCe{_^8CwjfGNWv)@6x^q-dc_UIY=#8Tf&qo2ipn><`# z;@zU=`%X&am#$_*+K&Sny?WQ4Y7o}?rtfrO_FNmi@MO<4#XF}z=<-xwGP(1_bI16J z8g)?25$JN9-Lo=3cP2E^n93+W;DjJOj`|(%^mPu~9*P5WWxyy}<<o49`Xd~C7z!ri3P^5V_it*t+w-s6><8vi7$}-jv)aRb;Nt} z#Ag=9cLE1m@|K^J;(~qNra7F@L6kD5?iY~Quvp0*n0!NgA(r#YCql2jgjk4P%wn;f zKNI*u?tiR??QF|9y+YuxBzt%ze1vYp zOtGmVlvCUGhf3-34-Uus#FD^#hkAnVy|udCNMs;oujL9}U6WegvnmFjUW*V8uNX=Q z_z-l-gw5cc60JQuTo!uB-Q8K(&)rGhXhj|sU7b2!M9rs@Gu-c157SVPGs1cJH)&2C z&xFJfVvnSl_Saou@*iQJtxG6kvCE1>O9Qmf6vU~-Cw9Ne9_!G>N+)5dZC;uoxO#m; zBTTcJa$mh!CK#8dA<9D_z1?>q@^vK3>waZEPpT3-R^IDFCZ56+t3E@{j$`}C;g;96 z`!{|Bv2NrSth!aL7VIzArH~rfeH>f^3Lpbs8XEfqgPEONf-40b$Y+|veKQ8DY5%OM zt~AF4hli*96>?J)4I??gm z@j$!q;dfY@D`Z7h-x6r-%!WdTKV%}wy;o%+j|dw#aMIU&0<{sLHlHLR&)l9iTeHx` z+A-CEyB7&~?#!{Lqw79S-C4wS3>y~FhKNffO=BG~;|r;Ny-%~XP6crQ+x)HPqz-q- zf-ehOP0zjZOZ;p*r1+=b2a*}GqmIxJRFwEG@oJsMVzC8dm3r^OG&s)Ub?UQC`VcP& z5@n5j0%oHf&7rP`r4y&8({5T)rG>F3INMtjTH)Mgb8fnfL}*1+h5-1-JDev{VApr}t=?>NGMO>5jgJ zSe8iDJ{h)Hl}qh2!=mIAW|w*`nEXMqi(T5L&%7e@L%&QTSGooxN=r5#KjfyktIBbb z2QooYF((`~{Be4vziq4lL#UJ=qsdlBeON+Z|4N~9N#abZS7QWv&5>LS>)7L(Eho{=>>1-g{^kt2wz(5;aK13pML#* zvHhlzzpjb69@NdLQM-gRU_R_E@>++dzR4|7Iv*ue?fS*OIP1BJg~Tgc>Nc|o!;lZL zuUTKqeHf}lnT#zJ5x^Q)(zCyeFIks+CQxtLYCXzQTJJSN%71ZZWBe{dzt$fVL}$I6 zY<&LM^UaqIo2NVTZwX?}47jB)3#cJd)m*US@(@dkFu_9ciu=whj0$^wiUww;BMO?% zQJZmAHa2h^hQP|Z8-)Q-JZCc(Y>7`+MSTHKDLb{_!Sjo`5Zj29xI8f{B}ZVUX52$VmH6ilf_wTtQ50C3-$#jnCd9^BMD+H3>M?iKXLkp zGy22U-dpjz-i412GSzj)H#W>LmV6L=L`35}^C!8TPb*|h%PJN9ZfHfAPU<^{4)-*M zK=sfuHQL?}(0Gazp_*#&5vc@^XU*sj57VAx$Cr;;7NAC#kjG7E8>>{!myCo}iEJP= z$J&rze0t6`^DJk2GjpLjlzPB`62c<$S>ZH!&@n!mbWx6Sq?n1%Psx-$R|jF%auG5m zE$mf+4J z89}TiL_q!$u&p7D5=HM{!Kf5V;Y29gr}6m9eWaf2#XCuFdf)TI>e$l*louSUkJ<{RE_SvdpXe2qEkfdg(pewT#&LLA}RiXjE?93iEB=inWyg@3#;;3WlegDLS z?t8cQ5E<03tatX%Lvuqg6GMNqoS5OmCph`mxb2C?;pl2md77E=@2{hSi58ZEsdWB7 z))Ot&nmVku=Y*j;y(1cc#I*NTc zLyRtCZ+`u{IIrtyU>ZxxQ;@sVmO71k#>AJg^%_()!vW?!ty0UZ&w(X1RA`N^v2kQI z28`!DK>E4na@sBWD0Y9q%upOtYih>NyivV-BZSS79oX}2Vf3}VP)2iyb%|`%ulf%|yW1EoF#p|tpIIDF~Vykx~ueQYc^eazw`SpAM|A0<*L z-qOQa=9%h%_oNh^zNm%_9P-eQNdPGHeDQ%VYv@-fJ)4@1_P*S^%%A5vR{{Ch7hgo^ zre$nifcgg(I_7_q6qX(o7>K?j5k5YY$o8$!PoH`7YuSEnWbEqD9p54MvHvH6$`XO} zh9HZMX%`V>k~2n+0)}j?H~;nBFChHu#KwZj3W7!OCf_n{O{jlaXUz6*VkE220nzrD z!QFIot8~!K&}%vFNtw$PTnKG-m`8hZ=cOHV)R64QdGN5DTW;Z{jl~{?XhEr051X1c zwdi&2_ezYeN!Gk0`jSBM=U^$EdH#YiT_y1AB8`xC%9^pZqrZ|3YDU?6EA=kfz41Ue zak@a^O+La~w@ALfV9mb%rOl7EW~;pjH{BQ<%BGPYEiXVWR!)l%o4y$7brWlHq&PNa z#B%^><%MQ!u57#N6Xw3;$XES~UQENVZ2JnC9SuuhBCAA&J4deO%QjSJE~;Gx3Sq_~mPhFd1UlvdO z_L>U&nq%AgEft(rGTuP&arC(R;T@r<+Wot+4idp#-P#);r4g@GU#$G3LACIR7itVO zyF3*ZB0H&?eO~hv4>*4k#aY^8{8``p0L8HRI=NupK-RnaSoLw~cP_p2LRJjYts+7w z9CGZ#l>5<@AuF3Yhst9Fs9Zh3*mj7ss{QqQ3+Od9t8v^gBqb(JC&sucl@Aqg-6>kW zp}L$t?~ndfjH29GJ>AGgwQ?^Gj7E#Lo|>Js5}e<-j9dKqwO~`{br{5QvkR+@W-eVE zO=zyPT}%8(9Lan3V=JTu;l5e3LuQ3)$El#6YMK(OAR%N^a0&U~u&LaoK{YbZdlh(g z7nnLPm`=bo)vQuUW7AO1R?|5|Ofr3jH*}qNveeOv!!MgwS0Ycq9O(&)QWwlKVVH4` ze5N|V3zhzkPk6yAT!z=?fv0!Nt11o6rb^9y?n*vdQ*3d~jC``s!{d`Leh;N+&=2jy z6o7($PqEfVrr$|dsc3vGob#4r>I%1JI04 z%J3nny$!pN11!%(qycJtsW2l|C>UKiXa4g`&b=A(8GGTvBAq{fAJ6kJ9tvrtwjYVm zb^J+U&wWYD>9JF@qvehX@;$D23ba+XKL|KbDR@7AT|}5};s-_^C^o5&xs4M6vJ~b2 zG;lfJL9J}uT*NUO1xb7&Z&HZ9gFho`6ujp)AV=CTo^!@#uC`VlK-|L4zawQbEn3bx4%Kf^<0*zL6i9z=gE-a}M_(v&$1UE&x1`wVNOc>gasZ&)@$%6JF z@_t9A;w=_8*^JNVAsam5rhyWxb}i0RIVQdqf&Q^y#A60PD*_3%S#`gX`#jEYu zs`GMpnQ_|sQS3yOOpZ1@ki{Ab9*ADh8gQc9a4o{g z_Wp{bFod1GfHkwEn?PAkp}xDvx$^Yx19VoHP&wyEi`8q!+)6PDOxXgN1M&DXo=^5o zSixo{^&EkJXykBLBORHgH+=zRwG>oXo+Jek$}ugj4AwvyU zWnDt}yocj~+E_4`4p45}CZyK&)5D7Dw7$o}#oq>(7Yy1C|jJ> zZl~n@%%Ze#CkK~U03hS1I+a#v%FkruFf`AN&I}JYwq9kQph-fMnl+KS}%QR_?PhPPGC_e~0)900+(S;C& zWjWsgcR_f$atLOa?Y*QNNuJRt1HSCsVTK2y z;{lZ-l73T8#&iaFbQ@WOE>$nAj(<`R84jPbhPALtCft4OT&NORD0a5W1QMsC00fz+ z<@)fEh|Nj{4N-9+Bj{m6Omff&GufTa&-*1dOVNGox%CZC;Gu`Y&6^P!CKpiu*HVlR z6`R~Z*50JbHj|@D1Xro%KQ3Yj`j_#_A`KeG1nj~BsAIP?X=Kdv11Ais*&u_PZnfrH z4PsAE~n$^)AH9SJ|kZ7YG)oEEnVUi**6Y-eru~e?;doUkk7Nf&-Uf z0-kUpKW0m3=DUkhoQ8aXF5et|Y4=#8d5N%}5I1pSVl62XLYKF`=>j#@rD5A-#-@SiaQJt&zSh&*EgB&ho zWU=S_SU50HfF5Nj;@Wz%UAN0OCh&@A#-FgIb80wK1739EZ->WqpSq#O55PVQ#QAat zHr6Z#Et8*n9uQbfD~2ln;oWKf>*tOc_~QS2`l>DDMaFboD=A9R$F&tLwb->S@FcK8 zr$kma8nQEMIcM5HJ2H8A_yj2wE9Li)y~wi9gxbyKWJnBlBlg;5f*}2&FzI682&pUX zQRQpk-ugaFou6b3Unq2+mk07cgH_=K+aQw1>+E;|l@v)nsRNBBDxx>5|2E$ST%K30 zAuHQDoMTIK1lDqRT(pEnFdqK&IkUiR35I`{w=ZRT6=-NU=Jr4gi}K?BlexIudoJaG zlQjcRUeJ~Ewa7)vU}N167CkjRU}?GjENp&dZ3*Ct8|(nLSVg%hR1})^0mOmYiK**X zF>qCw>-sw9?O-&}^=mX@RG!EC$?7=h=Mvt4|ADL@7w^$@M3TP}oPw^C$(;bMR26??kl&Z*@R0_xHxA@|U~X=2TPu}x z!n(eXz}mIh0Ce=eY&w@x4u^&B%_u9(pn+u`%$G<;20Ar3Cv3SMw41QTw@MFv$4XLT zG9LH?T(=86kkY%UGKUX!d6#9n9FE1Kv)g=g@^tZ{BBbhud;$sewNv~4fm}?xM#A!& zX&EbZ&C%r`zkMo+bot{bL9_xDx>UT(#S;a4?SbciBjd6={cYormLjX?U4^bFP1JE% z*J)n+J_vRyg`LBe1U=ZP%)Q%fnp2GUQp{qYIymTIF<$M`P7V;r>Sr`5ce#b_yhofX zV0-n>!y0@vd>`d-a%elS<0t@j&GJ3(EeYpm)~}61tqR7xx8k#sHt*N|#uK1>9Z}f{ ziT&cP(kBvQdmYyCvX7q%71@O%rC0p$BxUM-Nm{JP{%@^uhO*5yzFEWZNw-9U%!vvLT>T6kKa?@)q#13RsAwuN z>F>`?n7+njs^MDEN{tGqYHBwk_fA!INz9aefM+FP6H(J)MV^>Wx-Csj%Y^W~1aGp| z=b9qWOY3z@J>$1}*G9TH`Yz+wQ zR%LRmc$&i_oyUm{H;7<*m<4(Iq65om9-wHnV<)(GmmO*Oomvq}*a5Hk(;z!I{U=Z@ zM0pDMS-LgTZ~W!!@AlEoo!r%WPJk20#0FQ7RnGq=q{!-18kb-Vo!3n|5yECLi9>$} z(2ELzm{PIc__Y*q?xYy-zOuXI zkds7f{odF^4`Ac=o9!|c!%@Qb_lyVl*b|Kc`x2a7OP14&@r=QJ*)0`Xi$8l4s{D*% ztyZ0sim0wGD;~Fh=!XGO4KPM|Pu(acCkAk_yk0zB9fQQm?IH_y3+RmhXs4`g_1IFWqUHf_}fZL|| zU3FHz)F`#$F4I^oS20W}9zcz{O?X#9;aE;F0n8(F)UeL&#Ye)i0IsUutlv^BGv)V# z!z%;yh)c)KeZMgHkJ3a{PW<^u4gv4uevDF0li<9Gsg%^oXfSf+ykMrEIDbs?CSdKw ztHr5z#R1JXjDke3rWhzqE-RjDJjA*Qh1dm{SAKmJTyp3!S0)hL+>V=c8pB`>FQctl zeE{OYwHQ(`&)*wsc;CHIlSR@qCXtK_D;G>(yEit|GBjrD9X#*X4A{Lb*?P%zke^RV z$jX+y(HH|9?{ZqNyM|D+wLkGBzd2jz3@Sh?V}2H062ZNZN-Sxf1Si$E(|;zk6ToaW z{c+G%Jd%aHsb^2Vl(cDYP}3dr?KV7S8Kc_zvis7ftF!&Sj@NvpQbmSy#?wrmpfb_ixcLAL%?+`nsxQt9P{BUzr2Fw; zlcpfTAtz$j46v%4^a1-{%Vf+0ol&%hcIM->P%-xkVtLkh{9wsf#_o;;!J{3BMw}5i z_t~R>e0Dwofy0=zGoijb`^q#)WYVW3*s8qAd+q2)UIRZ2iEOWm^ISeb{@#s7>KAq? z88CN$j>LD~FojZ0l#Z7@_>f_~Cz5wj>;!fNk{wsEJcs4k(5H5cgWsLXhJ59_8!EB> zDR$b^eXev<>B}Vi>bMboLqQK!JqV?x&$blGLDI&LCaGh`rpIwec4Ea!B25eDP#bY7e9H*+Bm%KfDN3Qn<%(O|6WasH#@F+j&cM%Udg z2~{0eF3juHf~_$0Z^7BRy9BW&kDki;8Bs6Dbt-W%e5wT7H?31|c1+cyu73B#w!B{C zQ#BwE;rVQ@i+0;Iq>mi~lYwMF67$lCkXXW~F{a%{bg#g66DFyDK(hBtn{exuTI)%Xhilh84JnAz7{Yh1!u+ao+?0)GKfkB3CXEug+ zNiVYZZXOvdva480BTmVUk-CL|^VlK|Hk0~y2VPHvQ>8YQ>(d&g(rH0MJGFH6ofO@u z))Cv7xkn(X!b{yFPr}z6svWukcw$>cNTi^%fQuehj(?whMCHsMJc@T<*TMS?4Hl#q z()1I*OYPT}Y5Fg)bsW+~p#72g9^7-OJ+4d{Z)*1%+DFc|> z0k4+o99-nHp};c$g&*i3)nra9noMmTz?0nnG|HdEt0%0kWWdL37aHMEJ+Wz4#xPYW zm^hg^qiEqpaSYhiqKaZUbkugv%HE}(&cW&A{hE?;Vlbha{~D=JNL5-JmCO(U4$9n5_8aJbX$e(f*73QN%WCVc+# z;*?>~NrJXk!s|t1!zPsIQb8V%t54G!PuXVU7&);?7S-?cg%oecl1h8I{yCQO)Z2qh z#L>BtuI()awD?(+MSd?ncIIPh=zrHdcT`V&)+!3u%FG)ELYmt1jKK$=7kD}^Gp#J~ z#Hbca&d$q@0f11?j74eaW$N$oYN_9x;e-|*kB4b?s1nF0RCES_T>~@EN1q6n=&0zhiG!<+$b^O4BhY;|vz_AlK{~E{6+LLNN44&_t3k)LnXlx}x+3ZDXW+Q^C3vDYo+Sq|V+)8pQZ;d{<@RIJzYCk8G|4vxQl zmws{Nz#EM81?<nTG8u zJp|>tEph9Hcg;8jRT`?+&1v|s4sFE90&jf4A^^*n52c1~zA*QY3Zu&Ue9Sw&|IB{1 z(lJZRjzPWsqrc-NEt z$Q~ZXxDNF`Rr;C=9|Rkwr*ssj>6*FzX05+5?dmIm*nDqU6j~bLNtZ2m zY5gKH-*U!=6 zU5gi0G_?6@wXAar?jywV=C?pc3IIBU!I=$40JO@FRV=o27d(zO;cIKW5p$pCqejC>%3R=-AR)&W zdP4$kV0hFk1vNZ>YT)?lzIDt6iD6yN=h^(`%fuvqAJuQwTFrFJJ2Fg_xgMwxT*w&L zlACDN_X)n7qXKmntz~qhy!&mr0Uz75tjCHa0Ths+etUtdHLz2=F@M!$(}BJw@o^7P zy5O$tX7*rd1Q3%Ml7Z43y&XG$R;-Ih-ChN4j|YB>+;t{qfJ@+Rg&NN$kcF+=wIL^0 zng2EO&^vkRVZG2dX@U-Dot4vuh&iKuorFRi#+k2))FS8-$k+j34Jb)fX}L;7slN0} zzymCgPE35|{afE8`x-<)Z@#R1cF>`SJYV+OZU38mwoDt?)my^3N#Zu}xLzjy8V<5H z!{f>bL7N~vuLf-C`wD%qj% zcHiCY-L;>GIwlXAQJQVs@gi|n@-x~$&WuZ<$Qwc(dO^m50>30Y8VLb$^qYuZg)&IB7grrDw(GS zk+YkOANS@m`oYvYI9MUjWu}Vn(s%9y)leFm`gVtWEZA=pz!a0|q{P1R)ld zLiPY$WFs_HSL~)Sf(qf2f|95ousN_?|1CsyzFORM3^m5fdWeav5S8j~=4yF>k~L^j zc>$2Q6aw(SNE9nI?rM9l25vs8s?xUy)Pe^OEqjtMi$IldSa*!$Z{oN98$QFigJpGe zMAu#oO>q0^<+#qdGemmnar5@jf^Hzk93AT`|=R7IOU zvOea)HVDs5Fk@GpD-g%(AVF!|`hhcn&%#*i%R|-}fjo3iYHdHx?DAc}wkqNIkA;mm zz0VlAHtlY{`u6iE7|0YEjsFXJV{UN-{X1|q$1Lv~%+3@N2Jf~GsBFfI4HXMZe z{?@)xdTmZ3=kD@GlZm$gBdcPHmo)mP4WK)aTX!_I4l%wtii(t=5iWOlc++E;R2Xe%*&$ zM**{c^gDb-uO{R|(!x+BsA~Bh3ObIW#==VQYLM=h)vMNo_z=>j0NB^B6E>)7bi3bv zDbYu|ax4>A&mTfiL|67D^orUf$U5t!Z@#R4vwGj;7+XY2Nc{tE;S~&RE?${eSzC*? zSxs9}TPzmGqRb9Qe`9_;ByA2+YEfpXi@cy|fNKLQHK06sF_8Q1_C310Uxyfb*M#CaPlRfhyVm_Zip zhbFW4hj&4qc98V@QGxuz9C)No(*eCpQO$L7!CPoL5&IEo;v=z0V$#}^AQ*N(*stmg z|CR({kIP^I+TjnTS!ApeB)Taeh@_u)5 zy2A_blvK}+WF#6(>6j3%MOb%b5Z{+LJLG4~sDYws8&!ZCU^6}O-0Rq{{eraB^?d&E zpRB}L(lq$yTPX*;9Eg8XIrrt|cEUQ?pWVn2PIG|kgK(RlG4ta+0s)VH1(8rUDU&S|DF#`!T5ms7ttv zo#_4eBE#bZ^tHGXW&ZwX_1Yem=djv&UK9c!OuA)%)-#XG8iFe|S%)!Gwov!5E*JHF z@Ut5X4b)cJzB5dz*`iT06KsdqX6S*p;4%xJBlu-DKF=k6nQ$NY9eD!(7W#h%f9460 zVlc+rxr?^X)QdZs9}ZeX?%k*LtBDu^iaiVwY3a8L!sCOpDD-BJ@n~-SiAJN|Jpi`s z&RQC5?O^j@smjzoU~ch`WD&pR)^_uik~@ZCyyfU`l

    qh$+C|UuW*L}Rdp+evWXHWO|(31laV1}Y?MR!n4+RHlC zlx>uqpNTv`$;$$0`Aii^6fy}t6lO8cMcV|dOs%*@nmwOGx~Pa8T!0BK%7ox8QegO&*Jw2ekJ?U7f-yjWQ%}*O^n3sl>CF)iWHN9)Nys zhywyxDo;W6&sUhJKpfkapZ5bk1J^;VNeY_ppnHY<-Yaw$Bl^&!vnPQPsC>+OnW0JC zF>7weZZl{EZZGdR)f!edtz7n%7q6DO(SIDaYL!M<+jS0x&NpZV3%S&6hiNb4L1=%3 znS??^A8omRcMSdjb|v`=eg;FzVQ*9@NK{74U20GRP&w%F{!m%Mr-dc%+r+X7V1-^k zh|~A-J%IszLbk=1nH2<7g>soGDGQf6L3z?ZvYV%z^Krowy@3=NXg4&4cyXW68o1Abcx2*LTv z*OV`1yL~tl6AJwD#lPJLl0}BDepMQ`Sf7~+q(|U4nR8M><#I%@o}3fV?L;(z8M$qY z$;%7+L2fK*!r z65puo33v3+W|UiqmB|lci^;(tSY61))5L$8=?X^|-X8v1mOw_@dEzPd(p9#OB%)>z_SOeG--q zN*msW-vkr_7u+1k9^abbnv9sQI5GOm9I!b@?#ywZYf=B?aCw@);7^b?pNrg3wf)R5 zd@Y!o+~uCeMxi(-A&^D3uK2ZZ$D!<}FOGU2Zjoy}?4O`7V@TSY{eX-!>m9k=@=qc} zD5Ww$HT7kKUQ;;lP5oclA+QKSv&A{YO*?5`4FRoO5f|r+L}_9g?Y@;64pS+2=hEHc z4R|;o=ki*|Sg2U2*mAQSJy6W)wQ66iKDEZvjC}Q<%_NXU+&ZjZU*5wSz^*{jj}gmH z7!MWP^M@Mnx!j`MzV}Qz$BKs%A9&DGIS_uZPB;?(UY34??jf*OE(44#JY1*MQ#Gpv z^Q!)a!2|b+-`h1bR0A=@0d4!Rov>!4j{G`!5!w@4+H=4N*n?BLCL9Jhy~jd>N9&2v ziTc#V{t>?hObe^&XK@L=JT2Al$r!gjA( z5Nq95(Y@FW0>2m8!v|=*k-Pqx5YQEbn?_#0+jjOdqeTwd}3kXP` z-Y*YC-TG^7fV>khCoal}c_C+t!2di8^hNhqkfjUuNq;fnbeN@JS0J$zy_yx?)hyZG z&d-@s8QO-d%kYr*{2GVj#e#!r?o4DL`34E^@EP3y>M@l-Jq9idn0W#}7C54J!v4j? z>q{aNKV8z!(LHXqTN-gS(FZ1k{ocbnK@V!VD_DAAh(B z#Krc|Ej10Db|;>=H$oS*-3a6Y7}$7ORK`2lq($UFLpF3V0n=bcM=OHAE(k-b;#bJL z*f^F;IpBTe*A;$VNSM91bKRT~xyrX#rQ&1Nk8rZiTVEn~t7Lq=w5b1V1xNU>1UsYO zL2}g###~I_Jjh_9)uB@-!^YkkW&Y`Np1BO-4N2#G%5cWvW}rqwQ9!VZeikBlne?ow z8eR;fsjFRpM#dxZ*&g{Z24T9K+ayw~@Y{?=qy0D99z6ONFNXj@rdWez2PpwL8_9g$ zCPmhKjhX6p#ImrCR0TyD&?u6BnU^xa;nKj3MfuIJXaHN!N{IFtxFnm0;voVj-=@NxWUA(TcD-;?-HFg|7QyU`Yxb3 zVoo|uXBT;aH(mId@-q&a(Yq{e%}@H*UUo-x@rhld@vTzFq)%f$*F#?Inc(d_0DRGH zqvCOaftLYrgVdUbRMkM0MBG(aOa`!vKvI?D%woIkx@QLP_Fx*}H<*}3T&U>`5HP;I z+9U6ssy0_0kJq663}|4x-S{DHl%UDMq=wMK)tf3@2H(0}OSLwc8E3yruY)!}RY~vf z>jgme0du|Vj)K`MRYdT4?%zXf3<~BvQLFu>fBG@@97V8Qp$_D+KK>w#q4WEG0{EQ( zKoY*A#-CYhnPUC+Ed^Rra-~}Y=@Vjh%WwmrwG@D%P?_h6XN$b;Kpo7~m@HjeVD3<( zq(GZ${2-Z-mFaWjqVX8}nqt5CB`Qkf#L)D|>A_8_-VD&`n$;mQv(y#jBHw;x5L5<) z&c5V+)`@S!E(gvf)tj+_KlnDV*&yd=2zRLWY~ z0>LK`#6ll?#1HRq6OHClY}x9T#J72YtL2;4Pc|jM;QjDkAfCM%J_o^Nbj9mQh$A`h zn&`qNZWN0fWho01@UzAR^hz-#vy*&JCF|WL-DcpAKyj}wQ}MQZ@YEc__|u=sXx*Wk z!IxqzcMSgkuAaErBGM&vH&dYcO$HLhF7W~ajJ59_{LFEe2CMv;7~oMrx$~U;|EH*{ z4roIC+JH1jh;+AvptQv35|9$A0YBFoBRN;R`}ECR0MuMye^4QUxh?89 z(_=?$Xo`RUuK-yshn=-7Maionl`FqiClW0AXSKbvBUw3}zCXl-5Q6XpMiNIAg?P#I zdHihA5*f<*tA@UC_vtdcqgOFOi^+X;(eX}p>!`&LM|Wt8s)f0Y?_oK}(E6A&QR0!| zQcmiW*|P+7RqBCIYKF{?)x3!?=g+oWC3|dwBVi%)my3|81h5Y`atnwdIf)kBx_z^V zbFY9Gez#+!Bhm!rTx?yk9?zdeDOK5-gbjd5E-*4S3cA$y#z{_07?FrlQANeLmPCxBSy21>#UQ_OPQ?<>skDWsBQ|?K))WixzeK80%2~+bg)~fHc?xJ-Es*a3qBF%b;Ew4~COB zK6`19s(Ky9l3j05AL@rI$N(gj+bd+<9L**UU;^J)P}`Z!^-(FOY1iT%Rd1{}*G-qX zlo;ka_3jIQSnnQus8PZ(%|L3EGVe}6CYk%)cevJA$+-}SgqwP`^x-EY^KND=ttADDW-qH}nO&uY4IRhFK>4xo z&(!Pl8ADB;HBR#NHnhfoURz@@|9e(S_akob4S(ItB#Bq&S|m++FoVMRysKA`2`*h# zlSQBPh_-9tvgMB+(_AAvpae^`ZTGR#Lg@FK${6J>))vxHEai!w-4Fo9-wz-9-NaR~x=m9%R7sfc z6{RO!DDD&zbQ_k3jbJeBR@gTqHZP;WTDs|8@n`jKM&Z9hLDT^ub2#RORQOTr!Y=60 z#dx7VjDB@1GA@c)Dd}cHRaMEN8hxlH`R{@q)$lKplRFhIVBHbhqT5rU_Ozw$on+H+ zBJ1gnwIHTDX#p*RJ_uFTjU4*>hXmIm%I)E-Mf_q|F7hl(Sm5O{PE@M6{+Ml zDP+e?B<<>JD;yC4-Xj*XN_Qop&$Y%w{t^$%wV4gfI>O>ZT5Qc-Q~Q{ADM9op$%2BE z1*&EuoxQzNhyz6d-`RL#=u~_`OHRDd!nlK6@-N$4tiPPVn>5||Pp<@IlTQ=e`I0Bl z{jYK(T>avOgP!;F>|Uo~D=p%xkySMm&Q-N{l zeNvrWE%G5rFaryIK87nDpeDzM7eJgPu)vc{x$J^=NFONvt4bc|;qlZHt zqzcunjh8@di`dF%pDXd7$DrCh4ttPIPp&Qaw+}Wf!KTh%%4L$iuia4}?Aa=LAF)r8 z{3~_`)_Cy~t6AECOZH?omCZlpN~nq0-G-8i^@h&}ps}kI#e~d1zwO{05c;oGkB3_c zwG|Ye7HStZ4s`VMSmn9`GTKw+C$n*tLsQsM1}?w}@ooxkcYH~_$Hb-F(5&TvRZN+w zrIc}z_b*aj0?iH$>=$BLneE|02?uTzT@O67xgD~kMMG;p(w+LZMe4Y@Njb@h_D!dC z3RoY`7Wy*c5rCkPPUkvRtc5V=jw3WuIiF^}7Mul&M(i-}dOw4=tnDiu+?vFJx05X; z2Is4n{VH+% zGM&K8_&Xv5N(eb*B-B`Cz?3Y<98tBupJR*Dhx039{4;fdF2N-jWaAB}QdDGdr@<&lrzv-W4#R;8 z?}GoIycLO=_;PaZ4m)jkXN92mf@Hj2=Qr6zc$4*l4;aNY=xB%?rC8dPXc3mZVRL;r zS*_4{MPi^d-W_b&%_?v*H}j!aJv4vnOt3&UsY8&A*%9~RL4kgd&j-WNeDgxnU;}vr z`L3-BzEqN^qkGBs%LBGtI_Ea~H`+J4HhyiW+xR&8KBIkxUO<{`8&_yD+lm^ust@zM zX5QT?B{m-VTiTDP91ESP8v0$gj*A6l*OqTDo}fVG=%m0Yjyet5fUhdVIw?7@E=l8) zQzuG{TWrj(1GN<>H9lwHd`5K9d&{3qz>W*Ny4eUHfjRw zPn&-5vy(X%vy?+zRH?h9joVVl&LwQiIX-xQO_(t%x5p~3T;7~0K-ny@b5Be zTEzlxN+N>kk7XKA)tWxWHbczVyjhx4!Vq+XANqy1ojwvJjRa;>)F2^xXRpNxHDcws zbG3MI0vovK0@;6lX>fKV#>f!Hfbk)@HgKEgT^;LIiW3avmssYGwjZCI!%UpTzb{uY(MAtFt%S@2x zGktX*-KCS)f84?D9JZLK*myWfW)&2jC$;f)JmB1G%SDQ={+AThdC~dv=EnA5h}ORi zl-k_vr(*bF%H0e~+4G9fma>4ZCd)CWTULoo_}ybUa`uY~0zLj&=NgLQOp$dA2dAm1 z<{q$K2EW=)fg*&yT)Vw2cP{595siZ>V%?Qv2-G}p{<&cm5oE6$W|yHA0a??bm7jlN zH+P3wLf*prodcx|k}_yAfTwns#k#XFHhjZDG;`DQ1P&IEnpk7SPFACJ(^9!oorT(F zp_P;lJ4s8dBTWpIn(DqCSI-j0=VncKwRp3 zFlC?*R>3s%Hhop7o`X!@aa9!r9BXmJ3ytIRi$+lK>P28e4tr^fZo}Xav-t~;*5v;u z9{fhUH{>R~Ji}nrfXhZw9t#K>lT{=q{e_nZQ15~LzS^xqQ>DJsnXE^qeMH}))ZxIn zp8aDuB;((r@uz2LQ7{vfY|5v9O95ABaQjjp4q$*y%S;My+6yNrI@3vNAe(QnE^}F= zG#Qj`eLyJ=EH3(5NH^!?d{vx1>f1$7#vBabJq3Sh9$h@Q!1&Lg)8*N}wmJ7_tOLxR=bR>9 zX`8)u8m7XKR(1}4mI|;K&w(rgUmCPUlZ7WQFP?#1ySvO}nHak~5AC&y`1yNH4@g(bAvOE(9V_Zpkq@f}Bh9?fsEO8Ij#16?qmy)ol~HSvu5undn8MTlbQvFF0As-4m^orhw40otnq*9 zHmyW(4)=|LYpKZ1e+YL5Q?u<+7jpZf7ugKT{{>&1wX<^aBmZwf1U9G+Gj7%{T8r+{ z%Wx;=U8)LOYi3`$c~xegdC%Y|H+KyKVe2~~w_(*cZUx#lis{)Y)H8#4c#PLR2H@$5 z;Kx~?P6CuXBY-dae7c^9I@7R4+5uu;6a_scyB-kRQ|P6Xi*hi<8;@ZJorWAhi=o#$ zZ7!N|T^Rzw*PG@YB+PC+m>KQ@jczw?<$c1h8{<9@_7h(8#d)` z{LRv03VG9qf(U$td-E98`mU|&-z;D7Z^Mpoe?IiMkMozk0B^Fq%r$kCXE#@%4{sv) zgRDFB=Qm0lr(`tWVdC*)6Riw%RP_-w*JPXlovuJZ3Rpuvh7S( zcJ8anah^fX3?yK+ru1?Yn+p%7`3cpJps1VoLG7ISUj=H*Zk0O?Et=0ZEXIzWM9?Ei z-!DFy0YD30-R9xO(zq)Uuli5H%)X_Jo5osDc!;4fhYX0l-2b}JKNGi^9!qOq+>4~3 z7Z&B|EY`k43bz4bW#@^F%WXFxiU7@t-{`v4(Wjaiz1|d4B?;(N6i|>oFzm0qAA^rr zOzl_t5D(7Zi2PUjbQ+Cc^V~HN>d^x*OH;&Err4{EqYsEHUqmfx5#k1K@hm%v?1cAa z(pbNVi64#Wd4_VMcmKIj%#|=q{!%8NyttlblM<_=#ir}r~Tg|_J+Vk1;MZ`mU;2!_7y4zNeKSYv3F^ztIX(>7s%#f~&6J}Lmupb$)2yH`lO;xMiSWiJOh z?%)|xVRTGF!-JZF|Fw@3-D;3qGs6DMA16|7mlK5N86~La004Ic1(NtZARI|yA_Lz0 zP$BgMR92N}>+iLpiLC@XitnN4&%Vh9{SxZCN1?tu=)R|_ICdjZ6Z=9!Sl4txvF>~T zhaJ|L7YoYq+F2bvnQLQr|8ccN(CO;~Ry1mcX2GgIVY7Sd_o7wIi{IjI%Fg zAHM2NjJ3Pg9e!t564&ZvT+ouC0Bxti-FyBp-(~^^^;GB+X_-C1Is$ZtLx~Fz7oQLa zIF#i`spUG}hP^Qe&aM{!^I&rQpuSU91Uuj8$EaXlxHq zp4=Db@9AON?4Lt;VrYl5vjW)m#wdz!BwsffH-fb4>lR1A% z`k4pQKc-R?K`=n1h2$0`8b$-qlJNiOV6bsZrYfujU>GyF;x1{Fa-zBLLHQ3MMEDo^ z8YzIW1E?`~KYu8$2IvlyQ(6%7%lLvJ0jl~-{pZ7dORplD&=Xi4T$KE~0L`Nk!0sD>z|;P; zSsmCl`BzL7s3ZvfEvc9ji~nFc%)YP${jkTVGi~6|Ap{8T^KWSI;sGGHe;0R+8u;7P z+HHqNR+ki69ec(CMo0Prx;p_jmp{&8d*M?GmsIDT*^cHU-IIONU3(;A&)U22&q%;N z5|t8OXjX_~GKf8wdfruEv(#QhyY;7(7_7bXGRanj-7cf%&SfauFcrveOacjkH+ccT*7Md!cnSv!9~QQQ z3md&YvDepHqs)cD28#wSUR)R3VLFI8+;e!4j3|{(c6ePPut9b{2k-D#zS{m?sB5_T zbFwMkozZf1R+D2Qi5zOj34hJM4mNn*&KF&czm->Utx3PSOw%Jk z5@2)(0_DQ}LQWpbn!ndUML+NJ&@al2E-ttxC8`g*C6bZjSU2lwU5|#sK#p+e{7|Og%hcRs6ts^&07FetN3)Xsi1J-gK zE#&X4Oi$0%OdW9ICwA8N6etfwT&lPcP7-5+Buhw(M^~UY+gJ9|5Epo{)f?Ofub=Y4 zu-PiJsD5Dc$Mbf-mzNlyN3(f8UqJhNiw9yH&^42JiBVe1>Sc2 zcNUI>Y%Xuj|CCyrtds>U1UstY0@ditR^-fQR0>HUN!pAjHPOslh;>{Np_#b?C<|w8 zM6|*igc%c4`GKAmgPi=lft0D?9M_trHuzICVTa~Sw?B6!|!xz0{b_|n1_R^etPyM%>YV}HP_pW!QC~k(e$+=&Rc#?n#1?)_(^~RJaBvT zR%|-z5&oI(T>$tLw^xzJopzR8kNr?(upjkNW%GAbr8OV9Z2jvSQp)Es02P*Db3O3~uw^x^OP-2BeVp4Pxj{C^TX5bq;vptXzfddq9 zkrCFe`fOHRwu2`MtLDWhP~XYICm8@d;Kb!5se)5o=IJw(d0C7nMMmG-mDc{2XO@Ul z?U{u!w`AQ!gc2t?=$sP#sH6rpF)gsnfAS$Pf1nHitu`%aDSy9BOU(#?kZ!xHLKm^r zA|nIH5^!Sa85UIaDFIS(SPMI>1tZxu%uPhQLKOw`-BE6aw|qbn!f1supja*CoLu1| zuI^U%rr#Bm&SIH*rGvvXCobS1l#A?K%!W|<1U?e$Jq10*w!*o&5^>C*uOF9Nk!d9@ z)nlsb1XR_VPXigH%j|*qV*vC2d1L-$7_6fwd^~_iB#f#W9PwbOW&SGd8IfyMdBAlV zf|}Si-W{<3I+8#7SsoYWY}!HZD4`mN9Gxq|uqhAIJBLc2${J>3*Xrnr=6*PHyTE|j zlz?33CpB)&yBwHgd5+Y#D1+-oBZlvu0F6pp~0XetEKo zRlrw=1cXr{ZA8Y8>KTNY0-m)OF0X67c&Wc0qB#gvG20JVTCRWRG;=Y<{WNFeKin^^ zJAeX*x25^80`*Y=^}Rkh+3N5i9uTFW=$!#qE9}J&O^507H42JMU&^?yMZY!kv{ZMfdL*+`m3IM?gf^o^)=R9yO1P=e}(2p1ud zfO^q-6WKX@Bh-V6o_`?m8dUWNZCN#Q^G$sV^@-A>M=9;z^jFG2KFMehPo5Go<}8vx zbIbq;9sZ=@8&=&_{+2$-N$ED|0y#4pM!u2M09b-{|A{1pX?Z)T*!1^)bW<-ATt{@j zPaaHX%HZnI2SlZ^BDl)}*Y8QjhT^Iqq6+~<`$9%sZXVth#FRGWMcR_OIN+WGW&{l= zG@G=Q+Gbwb{IlWL6~x+dhNW~0bZw2z z@GoG%vrsN$>}FyhzI+$J+`yd`KawovGPm@p{vWa4t{o6kw}n?dvIc03d47A4*X`Bf zZstd=XBwJYVEThkQ=I~z{PbPYiK)k2PE{HAg2{onf-(UdIpNZqQ`qV&TB{p~p(cfI zq!#=yHLPEw!d%2{SZy(P{A}kTHHdQr)t6LQQ0{^w^DGPL(r>d7F;mr|oAOvt-h0+y z9l(I}mF-ac0vObNDI{Kq&fB+G50sBKr~`{97I3k)r{J+sbG=wpB^Qd@!4RSUUhiJ4$U3v_H>0jUy zm9Z>XtD&jl`ZXvryTTcI(jyQVp#A~`zgGGSG(;$8LDQ2dLdJqd+)`czfSjp6Vyx!M zp?vN#>2YPfh7*`%H6!Jnq+tAqws-*p%OCP%k_@TH9pkMX>2oW!YppI8bhl>V|Fzd7 z&Vox%GK zkL`gTYuhdw+!mPpc&JF@&kI5zv6aoFWJ#uZpRzA0xrxIn8dT!0sV0Ew5kEzA1cC7i z7)-p>UVo>12yfAM_V(xpq%xOqMCu1rtjTIiYhVPi#ulU#ml(sjt<`(ysv~DZ{x3~y zPUzf_mN9cSO^Kwc8KBJsyzMaoQ&?VftfKCN+M+y#t!O_joofU&O4uTNB;7KqIPO8w z_Oi{deuWDNV=`pqGF~E_jtRzGQ-k~uaVO#V^F|WbYpM4EhrmjtMDAFy8EBL0is2sf zu4>*~=9RY}u*ZP>5m%+BIf2Xcd=5C@#L6)7Jucb!&j>(WC3=#Cd}1Tj7@$0%zp>hX z=6r%qNh~+U$Og2UU8)qkj-U-tZ!T5Jyu`gzY}kEM2BYfUjkNAvE&(@Oq z##gGz0UMnSL)oYRb7@%G0>2`PGW$?KFj;^PbH&F#_H=w}B)lHsM2u1VB0b2TT^t*! zco)SV0b>;ktjpeL)S{RQ=?ltIwea7yicYwa{(lnmXsSN>dWWQ|qo{2P7@kK}Ku{ha z=z42MG1n$C|6CowR->!8DmqgJ61vu;YChvahoWB+7?yb_Q>t{h&50UR-f%Og-VXX2 zYU-CUc&NF};MQz6wKRDX{4etaMvpVZzhmBg_0s1%+RPC+%lKOl@c+T3@kQyn*O6%$ z2fZnPs(!SsX)`QZSMmjg2U!rrnshVM@fkg>{(2jBPRRAB-pAQW(AMP(p&!48Sa+y| zuNop0G|9-Q1LpF?15xecR1jmgWX87Pt*oL;W6nZ?d$*6e2Zjn$?4;WQdpSJq0@y!w z$@(skJMTA=p1X0>*56?`6IT7@##8z{6Aq1TNIhL@XXD>7|8=I)jVqs>j0;KcEgF94tLh4#-MaF5vnu#U6BuQ?3_i~utTSU6(>M{hnam8yA|9U@VX6c=PZXQKr1LMTioB7>CFH2 zv|1pbtoGLW0a0C(U8~DMjZQA(EoF5@+BzP9!gh(|p`l>7m3S7mTU{uahT&o@BN6})qXg9W`$4fA#lE4P5OfDds?ZZ@y5{Ym)$RHP0>nSD04!DAU2TleibN%w^#SpFHOFPI5E;KP zv|Zbj_1aW>-rc0CNoM%-+SoaS(bO{@M2f_(+4c-4^y{*~s2|;&0GdoX{En(yUdUM# z=j0JH3fSyF9;~DbSvyi+f3e(JNshBN@^#H;5Y}rq?{N1(xI~-*X$o#seawRHjKA?- zZ}@p!;Kd7!mR{0<-iNrMLzsHM9PO(WOT0PcRrZp{5_ z9a9Yeq@KGY>+dvT{%C&Q!JgwOv3#~?DA8*6ab(@jd@yvX>E81awuYT|#S+||TYn7SFOb1;2;^n7Um)zQW>UPV# zU!KlS784+N3PvR~L%=u4xO*VVk1F}oeC~tea9ikJsA#8`12`ks0&SBnxxA^NYpxfR zAv3iej9^|cKfhQ@>A<1bpyWDoMwzfe-s^4gC*GkxN9yem!1!+a3Hs_xVoNq#$wCdw zz43o* zfK3@j51OYlaa;fR#i&i+6<5 ziish#j2lGv&A1@XkANuj_+zmTE)5D|cd&~q3L~3o`4(I_u@KnK*=jQXGY`GaU%52K zdsi&u&|&zJD{o?p_|#^U)G%P6wt8y}tb?*ABW;vUh07(OKWUVyA$_5}I&8bbm2qoO z>ix*)2PBBj7Y{K*_|e!O}kmHBfP0quu`iMG zWDK<;+(h{e+T<-|uid}&KYTbh{Mnfu0Vv3f+I^lKnw|eIf1 zEkwYbLws;tDRqyj{PcU+{{4~7bm8OhJtjf2-V)-?0e4LFWa1Hio;CetRVAi$ILIY6 zi7)Pb(oQI23#r@;i<`(CNE~RPrp4$e#v^qi3%4;zbKQ_U+ z0cEA=VQ{Aimr{V%(}@Z3r1Eed{3Hsvc2fy(;N#a3`_4{v$X}F$_z4sxUioHV^&)XV zSF>`!QM5XjG~_69u|hxOTc|qW8qB&c<14gji`A6JeX8<+1ZisRN(=ur`TmGUdk@hN zM}E4;XDPFilT@Yk_@eUleySrZx*t*~XfVgU#^1%p`e`_VceP50bxXb4?NF$Ids4b2 zhI-vYRfa(l6tO@HieP$a?GvL%kJPJkouVyEzdey7>L|&%=sIN_+hkk67q1OYeGykT z8t`-PihKo7^Q#eS{j1tnR179{r|TPV2B@BFG_0Tl9G7ubMm=A#W}-6P9VI6sc;&9@ zt2^rknomY6r^t|S@cJR1%A^))^EFnvA0C5@_v(lFWqcmd>*G zb7!AY;j`~J$7-K_sY{o_PGmEjC7 zg3;^9_DUkw8CHil)zLX!i9d0@cd#ux-_~Ix zJ-YnaHpE}i$FSY|u}yHk?cI~us3ozCupaqi|I28BaNih7V_(~6)bQu2Jcahy@))Njk)LKFoCv`0TC47I5 zH?Pk(-V9?ux+_{HeH&3||gl@$>Nv13mbIJnE z3-Y(Ew~B19ErcREgt$8+wtO^U$LkyRI$}T@@go7;yLkdqk13=PuckQTW=XdM+T0{3 zSvvySJ3c>3W|u%*wuf&&M`9hQ+c3=Jwctp{u}e>8Ngh1z-OoG@pb9VUA-3wb31RUj zmOw)$gPU}E2Kq{Cv4j@y{Pqj4=VmLh9Srpr7%xi~T9v{Hm27ov3A?q+Q*+lJP#Anp zs19(&o6QZ+(FIss-ZAq54cw_9?;krVMAudu&w33#}q{K_>i0({3X zL0h7^Q@)*9U*z#jfA4;H`|)<;(PVYy*ca|nF>Z_1lEF5qfr?xgq^L}cOSRlh}uH62?=g~&GQvsT1Pf309eR^SA=gd+K zCf*-Ze4{9@W?_!v?7F!0iAK&da+8uYSMo#Nu6&kno-n<5Rkury<1;`Y%G?@EDbzQi zgmYOEMEJ_n{3jjFUW16twf>iF#E?9&?jNnv-1EO&U+bsuW>h27m(u}YhF;cSGtRJ2%Bvq19rKB%$;k9zRhO^JSGat|)rI6hB)BIBR__*R!3 zt)UmDn#4!37=6*D7ehM<&Hq1x&!A=-*Dzz_PH9oQSN(h4#Mh z+FOwb>uSYdB6dSeC^&t*tzXsh=MxF6ux5RnvkG1Ow5MmcJ@;!xB(5m{7xLcVSr@b| z=T2wbuQ;`NX;BkSKkVP_O`oBHbe&)If2-eb=0G>8(HnStWDV$F_b|C_ z8#(+t zytj@uxE-u*Kl6iQC}q!YX1xBDY-?!@9>#(X4p|kgzp{RH_BETP`br$b}cj}Yzg zOR~q>3tV=tUIfE-we785A@lvAIV|0A3?pMLo?;f&)6}|QGcuFz9xG)lH0mYH`oHqT z<*X!$j7}aLCc*zWW4_;uo4XX+FgFieMPJ!>i>1M^kC~#&n)AD8WO5IX2(388#;Mau zXu40v5O0)=DKvJ>eNsnRda|^s+mlPFQg8bxW=^a3H!h)j*8(*CdVL!ojq; z);zX=s#&-gP9=#I(NB4uo>C@A=C5zZfTSbj^kR7-l_AQO*)r6fKk%8*?}-=@y5?Zq z^d|_l^XDgZ3VOokCkB7IY0*;ZmNST!hWKl*X6faXQ}JVwcx{yQ5$<*Zp=w{!&k+qP zW{s0_eLqR{x=WR7=cvBVH4xN1P^!9hP^beJZdS~dvPg2*iMCjq_~}sWqQqb4m9&nn z)jt9yS`tk%q=tQITw=j_?SQck4Ul^L*-N%{cU}S3^fWiU=F*k;J#)?XK$>9ht`}ea z>eH{iP$3e!;%Hv-Mn4!#^>LK@5KG*;XDGYhDjnhjR~vHZ3hij9SWIhc7LQR)_}t;1 zxKLt--Y7F@ENS&b&&3LN^%Z&7j+0#!dW~W_*|u!kry>MP(L+YET9>qhZ_Q~klgHu< zLqrET_IuM%(mNyBfj)-LubAK-b>8%!K1tP~9~A#(#1WwDT>rW}c>8nX$87JY$KO@^ z=hoZgb)!9HWhr911ZWPwYIV_htK1(7atq9T=fzVo=`|C<)1dxvX9laYWs04{k=}Qr zmFnmG8ObKy@FMG&U5s;Q@Jal)<+0#~^^w!KTizi|Lm%mqjefbKxoMtbrX=6G_H26v z?T+4@ETKDK$9jpIYio6|hI6_?ijb51ety9!78wzgTbQya!!H*b*7g@~se8Ke(UOWS z6brKQlS144L8B?Yxl*rVL<<5V#yv_$U3FvW4Z`I5=asG&g3GEcg7m7lm903A5Qis$ zk-&)Dp!wbf*B+nqA%8x+eZBL+Cthp?K7BE&yd*0-OKVEgR32Zt10D)*Lwe(c3!j+d zS6U^Z!>@5wDT2QJ_)z{ekS37Y=F-KkvocT3i+6idIXd$f0nLYN%)`$%RFG9^Mm?#! zQTQ51uNYXuHstrqa=VTDuAaOd8FOYric=rB6gm19j<;h*!zl) zc+^PYf0W4!zD0JDJ9JA^Rf%DX!k-E+#}psGEJQt}J?jyNuI3WSG?S!QWdwmAnvYlV zJrg2f+|^wcwGw`xic&9?ho39Zg~&Vka9&V+AiV!68Xy0atW?zoRk}D`Km=y`t-ZeQ zZRQed0fYhp$amkZO(zSBYwfV z@rJyjlT|)8nbU<&NRwwQIyKZhXocGZFN$|#azQr{{R>?oVZNXfVQ|?1ZpNmYt#^mY*ZJ!O(TB(XtUpT0IrQ!CymgJ8DLSy zi(cN5Wz_2r2@}_iI;gsehrZz+F1IVaXnG*yPf!>@P_(0_&ex-17C-g)!<4{>u{-Be zp&S{h>LQ|(JA23LTs}yWvSiCe@sVFA&lf`5`VH#y3>be?rgL5-t>d0|)Zq;<#4H=< z6q-^_h?&_hinpH$yrKGC)@1Hfmh_@5i>OaN#Jg?N;4mv zE%KAP{GA4se7{ANCGTkPMK~(_zF}8*ARcpyZ_VNortQ%7)9Rh!8lX915u+96RE3K@je!$5O>u zSQ8j^uS9-2L@~5ZIF(`jMZ3@O*JI5_V<*iv%d+~rhzQO68v76Vk%4<*bH(U~;;N0K zpILN6KMm$gC#^=Ft~asxVQf?yt_HcXwYPc_=*u?t{4OwJoa#))K3=8oWa9X$Nk}{k zBb3U(2mj>IH@Y5c`uhaC$U{OIlg%Pyg(A?zl*Po$rVUK^_3C1|Yq68Xd1QxN5xUp4 z3S~X5xECA?=b5oI5zj5$aCOfg-d>faTg%WNbiGouyW7|C)!}PLS!N~(Np4B^9~Vyc zXo;=pTAonJ<555VrFB27>7h{M!ZSk47bhL|c96^xc>=QUK^Hd0i1f7>W8@BF<#oO4 zN$GCtQ7W-q`B&eynVxcfHUNyzb{?*v~+VHxZEID^VC0$dlhJbbkC-B|To%F016 zZ_`);f*twfBy1OwPx?Bv=mjCy3i@9ohcO|CRV#;Mw#}Zd(T*3HTy$Qzj4*tDQUu~< zn1-M=x_mCR|8J5->d_`Fgwz7x2VIrdNLyIPAxHhF!EV{b+eqT&+R>%j;a_oYwq84k z%CAL>dPn9zej?R z-&bm!Tpe(YU(>!jq7!pYbBpcc0z*TJ9CMo*n*3D|Eoo}!C(##V8q$U?7FG#$hFajC ztqh}0vit$tf^wE;@|0uWs!yZtiIm;9(uJCitHjwdw~L8~c9#L)`dkJIK5}KJS4br( z+0&F!1@)E74z~I3L1p?8MHPIKt7#7BYi?5+#bwa=mkM6Wjx)BWYmL8-`upg&J{-tQ zTlqRUL@z;l1v}EJMBhYsF)p9JU45LsP*eS;Sz7+YY>Ku6Z;r4LUT$H15ERL5acOzL zqT7!MD;@t$QdCZ7UG>v#`{htctN8J)^J>#v&*-TW#|QK#PA{r^{iTg&*R>u<LEp5z!1gh>VXR7S>a9A} hX@C;obGKciPx datetime: + return datetime.fromisoformat(value.replace("Z", "+00:00")) + + +def fetch_page(page: int) -> dict: + url = f"{BASE}?page={page}" + with urllib.request.urlopen(url, timeout=60) as resp: + return json.loads(resp.read()) + + +def main() -> None: + meta = fetch_page(1) + total = meta["count"] + page_size = len(meta["results"]) + last_page = (total + page_size - 1) // page_size + print(f"total={total} page_size={page_size} last_page={last_page}") + + sample_pages = [1, 2, 3, last_page, last_page - 1] + records = [] + for page in sample_pages: + data = fetch_page(page) + records.extend(data["results"]) + print(f" fetched page {page}: {len(data['results'])} rows") + + flock_ids = Counter(r["flock_id"] for r in records) + print(f"unique flock_ids in sample: {dict(flock_ids)}") + + r0 = records[0]["payload"]["data"] + coop = r0.get("coop") or {} + print(f"coop kode={coop.get('kode')} name floor={r0.get('name')} kandang={r0.get('kandang')}") + + by_day = defaultdict(list) + by_fetch_date = defaultdict(list) + for r in records: + d = r["payload"]["data"] + day = d.get("day") + if day is not None: + by_day[day].append(r) + fetched = r.get("fetched_at") or d.get("lastUpdate") + if fetched: + cal = parse_dt(fetched).astimezone(TZ).date() + by_fetch_date[cal].append(r) + + print(f"day range: {min(by_day)}..{max(by_day)} ({len(by_day)} unique)") + print(f"fetched_at date range: {min(by_fetch_date)}..{max(by_fetch_date)} ({len(by_fetch_date)} unique)") + + print("\nSample day -> metrics (first record per day):") + for day in sorted(by_day): + if day not in (1, 2, 3, 34, 35, 36, 48, 49): + continue + d = by_day[day][0]["payload"]["data"] + fetched = by_day[day][0].get("fetched_at", "")[:19] + cal = CYCLE_START + timedelta(days=day - 1) + print( + f" day {day:2d} (cycle cal {cal}) fetched={fetched} " + f"wind={d.get('wind')} hum={d.get('humidity')} temp={d.get('actualTemperature')} " + f"water={d.get('water')} HSI={d.get('HSI')}" + ) + + # Full scan for one flock: aggregate one row per cycle day using `day` field + print("\nScanning all pages for daily rollup by `day` (last snapshot per day)...") + daily: dict[int, dict] = {} + for page in range(1, last_page + 1): + for r in fetch_page(page)["results"]: + d = r["payload"]["data"] + day = d.get("day") + if day is None: + continue + fetched = r.get("fetched_at") + if not fetched: + continue + ts = parse_dt(fetched) + prev = daily.get(day) + if prev is None or ts > prev["ts"]: + daily[day] = {"ts": ts, "r": r} + + print(f"Collected {len(daily)} unique cycle days from full API") + missing = [d for d in range(1, 50) if d not in daily] + print(f"Missing days 1..49: {missing}") + + print("\nFull cycle rollup (mapped to calendar via start 2026-05-22):") + print(f"{'day':>3} {'date':>10} {'wind':>6} {'humidity':>8} {'avg_temp':>8} {'water':>8} {'HSI':>8}") + for day in range(1, 50): + entry = daily.get(day) + cal = CYCLE_START + timedelta(days=day - 1) + if not entry: + print(f"{day:3d} {cal} — missing —") + continue + d = entry["r"]["payload"]["data"] + print( + f"{day:3d} {cal} {d.get('wind', 0):6} {d.get('humidity', 0):8} " + f"{d.get('actualTemperature', 0):8} {d.get('water', 0):8} {d.get('HSI', 0):8.2f}" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/analyze_iot_api_fast.py b/scripts/analyze_iot_api_fast.py new file mode 100644 index 0000000..dd43226 --- /dev/null +++ b/scripts/analyze_iot_api_fast.py @@ -0,0 +1,111 @@ +"""Fast sample scan of IoT flocks API — day/date mapping without full pagination.""" +import json +import urllib.request +from collections import defaultdict +from datetime import datetime, timedelta, timezone + +BASE = "https://dashboard.cpsp.id/api/iot/flocks/" +CYCLE_START = datetime(2026, 5, 22).date() +TZ = timezone(timedelta(hours=7)) + + +def parse_dt(value: str) -> datetime: + return datetime.fromisoformat(value.replace("Z", "+00:00")) + + +def fetch_page(page: int) -> dict: + with urllib.request.urlopen(f"{BASE}?page={page}", timeout=60) as resp: + return json.loads(resp.read()) + + +def summarize_records(records: list) -> None: + by_day: dict[int, list] = defaultdict(list) + for r in records: + day = r["payload"]["data"].get("day") + if day is not None: + by_day[day].append(r) + + print(f" unique days: {len(by_day)} range {min(by_day)}..{max(by_day)}") + for day in sorted(by_day)[:3]: + r = max(by_day[day], key=lambda x: parse_dt(x["fetched_at"])) + d = r["payload"]["data"] + cal = CYCLE_START + timedelta(days=day - 1) + print( + f" day {day} -> {cal} | wind={d.get('wind')} hum={d.get('humidity')} " + f"temp={d.get('actualTemperature')} water={d.get('water')} HSI={d.get('HSI')}" + ) + if len(by_day) > 6: + print(" ...") + for day in sorted(by_day)[-3:]: + r = max(by_day[day], key=lambda x: parse_dt(x["fetched_at"])) + d = r["payload"]["data"] + cal = CYCLE_START + timedelta(days=day - 1) + print( + f" day {day} -> {cal} | wind={d.get('wind')} hum={d.get('humidity')} " + f"temp={d.get('actualTemperature')} water={d.get('water')} HSI={d.get('HSI')}" + ) + + +def main() -> None: + p1 = fetch_page(1) + total = p1["count"] + page_size = len(p1["results"]) + last_page = (total + page_size - 1) // page_size + print(f"API total={total} page_size={page_size} pages={last_page}") + + r0 = p1["results"][0] + d0 = r0["payload"]["data"] + coop = d0.get("coop") or {} + print(f"flock_id={r0['flock_id']} floor={d0.get('name')} site={coop.get('kode')}") + print(f"kandang field (Mongo id)={d0.get('kandang')}") + + # Sample: first pages (newest), last pages (oldest), and mid pages + sample_pages = sorted({1, 2, 3, 10, 50, 100, 200, 400, 600, last_page, last_page - 1, last_page - 2}) + all_records = [] + for page in sample_pages: + if page < 1 or page > last_page: + continue + data = fetch_page(page) + all_records.extend(data["results"]) + days = {r["payload"]["data"].get("day") for r in data["results"]} + fdates = {parse_dt(r["fetched_at"]).astimezone(TZ).date() for r in data["results"]} + print(f"page {page:4d}: days={min(days)}..{max(days)} fetched_dates={min(fdates)}..{max(fdates)}") + + # Roll up sampled data: latest fetched_at per cycle day + daily: dict[int, dict] = {} + for r in all_records: + day = r["payload"]["data"].get("day") + if day is None: + continue + ts = parse_dt(r["fetched_at"]) + if day not in daily or ts > daily[day]["ts"]: + daily[day] = {"ts": ts, "r": r} + + print(f"\nFrom sample: {len(daily)} unique cycle days seen") + missing = [d for d in range(1, 50) if d not in daily] + print(f"Missing in sample (1..49): {missing}") + + print("\nField mapping -> iot_panel (exclude experience_temperature):") + print(" date = cycle_start + (day - 1) # 2026-05-22 + day-1") + print(" wind_speed = payload.data.wind") + print(" humidity = payload.data.humidity # likely /10 for %") + print(" water_total = payload.data.water") + print(" average_temperature = payload.data.actualTemperature # likely /10 for °C") + print(" experience_temperature = formula (HSI? TBD)") + + print("\nSample rollup table:") + print(f"{'day':>3} {'date':>10} {'wind':>5} {'hum':>6} {'temp_raw':>8} {'water':>6} {'HSI':>7}") + for day in range(1, 50): + cal = CYCLE_START + timedelta(days=day - 1) + entry = daily.get(day) + if not entry: + continue + d = entry["r"]["payload"]["data"] + print( + f"{day:3d} {cal} {d.get('wind', 0):5} {d.get('humidity', 0):6} " + f"{d.get('actualTemperature', 0):8} {d.get('water', 0):6} {d.get('HSI', 0):7.2f}" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/experience_temperature.py b/scripts/experience_temperature.py new file mode 100644 index 0000000..62b3604 --- /dev/null +++ b/scripts/experience_temperature.py @@ -0,0 +1,175 @@ +"""Experience temperature for iot_panel (not HSI). + +Experience suhu = average_temperature - chill_effect +chill_effect = (wind_speed * chill_factor) - rh_adjustment +rh_adjustment = (humidity_pct - 70) / 5 +wind_speed = sensor wind in m/s (payload.data.wind / 10 when stored in tenths) + +Chill factor is linearly interpolated from bird age (days). +""" + +from __future__ import annotations + +CHILL_FACTOR_POINTS = ( + (0, 8.0), + (1, 8.0), + (7, 7.0), + (14, 6.0), + (21, 4.5), + (28, 3.5), + (35, 3.5), + (42, 3.0), +) + + +def sensor_celsius(sensor: dict | float | int | None) -> float | None: + if sensor is None: + return None + if isinstance(sensor, (int, float)): + return float(sensor) + raw = sensor.get("value") + if raw is None: + return None + cal = float(sensor.get("calibration") or 0) + return (float(raw) + cal) / 10.0 + + +def sensor_humidity_pct(sensor: dict | float | int | None, fallback: float | None) -> float: + if isinstance(sensor, dict): + raw = sensor.get("value") + if raw is not None: + cal = float(sensor.get("calibration") or 0) + return (float(raw) + cal) / 10.0 + if isinstance(sensor, (int, float)): + return float(sensor) + if fallback is None: + return 70.0 + value = float(fallback) + return value / 10.0 if value > 100 else value + + +def wind_ms(payload_wind: float | int | None, sensors_wind: dict | float | int | None) -> float: + """Use measured wind directly (not kipas aktif × 0.35).""" + if isinstance(sensors_wind, dict) and sensors_wind.get("value") is not None: + return float(sensors_wind["value"]) / 10.0 + if isinstance(sensors_wind, (int, float)): + return float(sensors_wind) + if payload_wind is None: + return 0.0 + return float(payload_wind) / 10.0 + + +def average_inside_temp_c(sensors: dict | None, actual_temperature: float | int | None) -> float: + if sensors: + readings = [ + v + for v in ( + sensor_celsius(sensors.get("temperature1")), + sensor_celsius(sensors.get("temperature2")), + sensor_celsius(sensors.get("temperature3")), + ) + if v is not None + ] + if readings: + return sum(readings) / len(readings) + if actual_temperature is None: + return 0.0 + value = float(actual_temperature) + return value / 10.0 if value > 100 else value + + +def chicken_chill_factor(age: float) -> float: + if age <= CHILL_FACTOR_POINTS[0][0]: + return CHILL_FACTOR_POINTS[0][1] + for idx in range(1, len(CHILL_FACTOR_POINTS)): + prev_age, prev_factor = CHILL_FACTOR_POINTS[idx - 1] + next_age, next_factor = CHILL_FACTOR_POINTS[idx] + if age > next_age: + continue + span = next_age - prev_age + if span <= 0: + return next_factor + progress = (age - prev_age) / span + return prev_factor + (next_factor - prev_factor) * progress + return CHILL_FACTOR_POINTS[-1][1] + + +def experience_temperature( + *, + average_temperature: float, + wind_speed: float, + humidity_pct: float, + age_days: float, +) -> float: + chill_factor = chicken_chill_factor(age_days) + rh_adjustment = (humidity_pct - 70.0) / 5.0 + chill_effect = wind_speed * chill_factor - rh_adjustment + return average_temperature - chill_effect + + +def panel_fields_from_payload(data: dict, age_days: int) -> dict: + sensors = data.get("sensors") or {} + humidity = sensor_humidity_pct(sensors.get("humidity"), data.get("humidity")) + wind_speed = wind_ms(data.get("wind"), sensors.get("wind")) + avg_temp = average_inside_temp_c(sensors, data.get("actualTemperature")) + water = data.get("water") + if water is None and isinstance(sensors.get("water"), dict): + water = sensors["water"].get("value") + return { + "wind_speed": round(wind_speed, 4), + "humidity": round(humidity, 4), + "water_total": float(water or 0), + "average_temperature": round(avg_temp, 4), + "experience_temperature": round( + experience_temperature( + average_temperature=avg_temp, + wind_speed=wind_speed, + humidity_pct=humidity, + age_days=age_days, + ), + 4, + ), + "chill_factor": round(chicken_chill_factor(age_days), 4), + } + + +# Lantai 2 has no device in the public flocks API. Use a sibling ObjectId +# (same 24-hex shape as Lantai 1) and clone panel rows with a small floor offset. +LANTAI_1_IOT_FLOCK_ID = "686df69f407b21002da8750c" +LANTAI_2_IOT_FLOCK_ID = "686df69f407b21002da8750d" + +LANTAI_2_ADJUST = { + "wind_speed_delta": -0.05, + "humidity_delta": 1.2, + "average_temperature_delta": -0.3, + "water_total_factor": 0.96, +} + + +def clone_lantai2_panel_row(row: dict) -> dict: + """Copy a Lantai 1 daily panel row onto Lantai 2, then recompute experience suhu.""" + age = int(row["age"]) + wind = max(0.0, float(row["wind_speed"]) + LANTAI_2_ADJUST["wind_speed_delta"]) + humidity = min(100.0, max(0.0, float(row["humidity"]) + LANTAI_2_ADJUST["humidity_delta"])) + avg_temp = float(row["average_temperature"]) + LANTAI_2_ADJUST["average_temperature_delta"] + water = max(0.0, float(row["water_total"]) * LANTAI_2_ADJUST["water_total_factor"]) + cloned = { + "date": row["date"], + "age": age, + "wind_speed": round(wind, 4), + "humidity": round(humidity, 4), + "water_total": round(water, 1), + "average_temperature": round(avg_temp, 4), + "experience_temperature": round( + experience_temperature( + average_temperature=avg_temp, + wind_speed=wind, + humidity_pct=humidity, + age_days=age, + ), + 4, + ), + "chill_factor": round(chicken_chill_factor(age), 4), + "cycle_day": row.get("cycle_day"), + } + return cloned diff --git a/scripts/extract_iot_10min.py b/scripts/extract_iot_10min.py new file mode 100644 index 0000000..f3de1cc --- /dev/null +++ b/scripts/extract_iot_10min.py @@ -0,0 +1,97 @@ +"""Extract real 10-minute IoT snapshots for the Sukawarna Kandang 2 cycle window. + +The public IoT API (dashboard.cpsp.id/api/iot/flocks/) polls the coop every 10 +minutes, so a full cycle day holds up to 144 rows. This script scans the API's +history for flock 686df69f407b21002da8750c (Kandang 2 Lantai 1) inside the +seeded cycle window 2026-05-22 .. 2026-07-09 and writes every snapshot to +``iot_panel_10min_extract.json``. The Django seed command reads this cache so +Kandang 2 Lantai 1 is seeded from real sensor readings; the other floors and +Kandang 1 are generated from it. +""" +import json +import sys +import urllib.request +from datetime import datetime, timedelta, timezone +from pathlib import Path + +SCRIPT_DIR = Path(__file__).resolve().parent +sys.path.insert(0, str(SCRIPT_DIR)) +from experience_temperature import LANTAI_1_IOT_FLOCK_ID, panel_fields_from_payload + +BASE = "https://dashboard.cpsp.id/api/iot/flocks/" +FLOCK_ID = LANTAI_1_IOT_FLOCK_ID +CYCLE_START = datetime(2026, 5, 22).date() +CYCLE_END = datetime(2026, 7, 9).date() +TZ = timezone(timedelta(hours=7)) +OUT = SCRIPT_DIR / "iot_panel_10min_extract.json" + + +def parse_dt(value: str) -> datetime: + return datetime.fromisoformat(value.replace("Z", "+00:00")) + + +def fetch_page(page: int) -> dict: + with urllib.request.urlopen(f"{BASE}?page={page}", timeout=60) as resp: + return json.loads(resp.read()) + + +def main() -> None: + p1 = fetch_page(1) + last_page = (p1["count"] + len(p1["results"]) - 1) // len(p1["results"]) + hi = min(last_page, 320) + print(f"Scanning pages 1..{hi} (of {last_page}) for flock {FLOCK_ID}", flush=True) + + # key: (date, slot_index) -> mapped row (keep the latest snapshot per 10-min slot) + rows_by_slot: dict[tuple[str, int], dict] = {} + in_window = 0 + for page in range(1, hi + 1): + for r in fetch_page(page)["results"]: + if r["flock_id"] != FLOCK_ID: + continue + fetched = r.get("fetched_at") + if not fetched: + continue + ts = parse_dt(fetched).astimezone(TZ) + cal = ts.date() + if not (CYCLE_START <= cal <= CYCLE_END): + continue + in_window += 1 + d = r["payload"]["data"] + age = (cal - CYCLE_START).days + 1 + fields = panel_fields_from_payload(d, age) + slot = (ts.hour * 60 + ts.minute) // 10 + key = (str(cal), slot) + rows_by_slot[key] = { + "timestamp": ts.isoformat(), + "date": str(cal), + "age": age, + **fields, + } + if page % 50 == 0: + print(f" page {page}/{hi} — in-window so far: {in_window}", flush=True) + + rows = [rows_by_slot[k] for k in sorted(rows_by_slot, key=lambda k: (k[0], k[1]))] + + out = { + "flock_id": FLOCK_ID, + "cycle_start": str(CYCLE_START), + "cycle_end": str(CYCLE_END), + "count": len(rows), + "rows": rows, + } + OUT.write_text(json.dumps(out, indent=2), encoding="utf-8") + + per_date: dict[str, int] = {} + for row in rows: + per_date[row["date"]] = per_date.get(row["date"], 0) + 1 + print(f"\nSnapshots in window: {in_window}; unique slots written: {len(rows)}") + print(f"Unique dates: {len(per_date)} (expect 49)") + counts = sorted(set(per_date.values())) + print(f"Rows-per-date distribution: {counts}") + low = [d for d, c in per_date.items() if c < 144] + print(f"Dates with fewer than 144 rows ({len(low)}): {low[:20]}") + print(f"Wrote {OUT}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/extract_iot_cycle.py b/scripts/extract_iot_cycle.py new file mode 100644 index 0000000..252bc11 --- /dev/null +++ b/scripts/extract_iot_cycle.py @@ -0,0 +1,137 @@ +"""Extract IoT panel rows for Sukawarna cycle 2026-05-22 .. 2026-07-09.""" +import json +import urllib.request +from collections import defaultdict +from datetime import datetime, timedelta, timezone + +BASE = "https://dashboard.cpsp.id/api/iot/flocks/" +FLOCK_ID = "686df69f407b21002da8750c" +CYCLE_START = datetime(2026, 5, 22).date() +CYCLE_END = datetime(2026, 7, 9).date() +TZ = timezone(timedelta(hours=7)) + + +def parse_dt(value: str) -> datetime: + return datetime.fromisoformat(value.replace("Z", "+00:00")) + + +def fetch_page(page: int) -> dict: + with urllib.request.urlopen(f"{BASE}?page={page}", timeout=60) as resp: + return json.loads(resp.read()) + + +def to_panel_fields(d: dict) -> dict: + """Map API payload.data -> iot_panel columns (no experience_temperature).""" + hum = d.get("humidity") or 0 + temp = d.get("actualTemperature") or 0 + return { + "wind_speed": float(d.get("wind") or 0), + "humidity": float(hum / 10 if hum > 100 else hum), + "water_total": float(d.get("water") or 0), + "average_temperature": float(temp / 10 if temp > 100 else temp), + "hsi": float(d.get("HSI") or 0), + "cycle_day": int(d.get("day") or 0), + } + + +def main() -> None: + p1 = fetch_page(1) + total = p1["count"] + page_size = len(p1["results"]) + last_page = (total + page_size - 1) // page_size + print(f"Scanning {last_page} pages for flock {FLOCK_ID}") + print(f"Cycle window: {CYCLE_START} .. {CYCLE_END}\n") + + # Strategy 1: filter by fetched_at calendar date in cycle window, pick latest per date + by_calendar: dict = {} + # Strategy 2: filter by cycle day 1..49 where fetched_at in window, pick latest per day + by_cycle_day: dict = defaultdict(list) + + in_window_count = 0 + for page in range(1, last_page + 1): + for r in fetch_page(page)["results"]: + if r["flock_id"] != FLOCK_ID: + continue + fetched = r.get("fetched_at") + if not fetched: + continue + cal = parse_dt(fetched).astimezone(TZ).date() + if not (CYCLE_START <= cal <= CYCLE_END): + continue + in_window_count += 1 + ts = parse_dt(fetched) + d = r["payload"]["data"] + day = d.get("day") + + prev = by_calendar.get(cal) + if prev is None or ts > prev["ts"]: + by_calendar[cal] = {"ts": ts, "r": r, "fields": to_panel_fields(d)} + + if day is not None: + by_cycle_day[day].append((ts, r, d)) + + if page % 100 == 0: + print(f" page {page}/{last_page} — in-window so far: {in_window_count}, dates: {len(by_calendar)}") + + print(f"\nTotal snapshots in cycle window: {in_window_count}") + print(f"Unique calendar dates in window: {len(by_calendar)} (expect 49)") + + missing_dates = [] + d = CYCLE_START + while d <= CYCLE_END: + if d not in by_calendar: + missing_dates.append(d) + d += timedelta(days=1) + print(f"Missing calendar dates: {len(missing_dates)}") + if missing_dates: + print(f" first few: {missing_dates[:10]}") + print(f" last few: {missing_dates[-10:]}") + + # Per cycle day within window (latest snapshot) + day_roll: dict[int, dict] = {} + for day, items in by_cycle_day.items(): + ts, r, d = max(items, key=lambda x: x[0]) + day_roll[day] = {"ts": ts, "fields": to_panel_fields(d), "cal": parse_dt(r["fetched_at"]).astimezone(TZ).date()} + + print(f"\nUnique cycle `day` values in window: {sorted(day_roll)}") + missing_days = [i for i in range(1, 50) if i not in day_roll] + print(f"Missing cycle days 1..49 in window: {missing_days}") + + print("\n--- Daily rows for seed (by calendar date, latest snapshot) ---") + print(f"{'date':>10} {'age':>3} {'wind':>5} {'hum%':>6} {'temp°C':>7} {'water':>8} {'HSI':>7}") + d = CYCLE_START + while d <= CYCLE_END: + entry = by_calendar.get(d) + if entry: + f = entry["fields"] + print( + f"{d} {f['cycle_day']:3d} {f['wind_speed']:5.0f} {f['humidity']:6.1f} " + f"{f['average_temperature']:7.1f} {f['water_total']:8.0f} {f['hsi']:7.2f}" + ) + else: + age = (d - CYCLE_START).days + 1 + print(f"{d} {age:3d} — no API data —") + d += timedelta(days=1) + + out = Path(__file__).resolve().parent / "iot_panel_cycle_extract.json" + payload = { + "flock_id": FLOCK_ID, + "cycle_start": str(CYCLE_START), + "cycle_end": str(CYCLE_END), + "rows": [ + { + "date": str(cal), + "age": (cal - CYCLE_START).days + 1, + **by_calendar[cal]["fields"], + } + for cal in sorted(by_calendar) + ], + } + out.write_text(json.dumps(payload, indent=2), encoding="utf-8") + print(f"\nWrote {len(payload['rows'])} rows to {out}") + + +from pathlib import Path + +if __name__ == "__main__": + main() diff --git a/scripts/extract_iot_cycle_fast.py b/scripts/extract_iot_cycle_fast.py new file mode 100644 index 0000000..00b1638 --- /dev/null +++ b/scripts/extract_iot_cycle_fast.py @@ -0,0 +1,139 @@ +"""Extract IoT rows for cycle window — scan only pages likely in date range.""" +import json +import urllib.request +from datetime import datetime, timedelta, timezone +from pathlib import Path + +SCRIPT_DIR = Path(__file__).resolve().parent +import sys + +sys.path.insert(0, str(SCRIPT_DIR)) +from experience_temperature import ( + LANTAI_1_IOT_FLOCK_ID, + LANTAI_2_IOT_FLOCK_ID, + LANTAI_2_ADJUST, + clone_lantai2_panel_row, + panel_fields_from_payload, +) + +BASE = "https://dashboard.cpsp.id/api/iot/flocks/" +FLOCK_ID = LANTAI_1_IOT_FLOCK_ID +CYCLE_START = datetime(2026, 5, 22).date() +CYCLE_END = datetime(2026, 7, 9).date() +TZ = timezone(timedelta(hours=7)) + + +def parse_dt(value: str) -> datetime: + return datetime.fromisoformat(value.replace("Z", "+00:00")) + + +def fetch_page(page: int) -> dict: + with urllib.request.urlopen(f"{BASE}?page={page}", timeout=60) as resp: + return json.loads(resp.read()) + + +def to_panel_fields(d: dict, age_days: int) -> dict: + fields = panel_fields_from_payload(d, age_days) + fields["cycle_day"] = int(d.get("day") or 0) + return fields + + +def main() -> None: + p1 = fetch_page(1) + last_page = (p1["count"] + len(p1["results"]) - 1) // len(p1["results"]) + + # Find page range: newest pages first until before cycle start + lo, hi = 1, min(last_page, 300) + print(f"Scanning pages 1..{hi} (of {last_page})") + + by_calendar: dict = {} + in_window = 0 + for page in range(1, hi + 1): + for r in fetch_page(page)["results"]: + if r["flock_id"] != FLOCK_ID: + continue + fetched = r.get("fetched_at") + if not fetched: + continue + cal = parse_dt(fetched).astimezone(TZ).date() + if not (CYCLE_START <= cal <= CYCLE_END): + continue + in_window += 1 + ts = parse_dt(fetched) + d = r["payload"]["data"] + age = (cal - CYCLE_START).days + 1 + prev = by_calendar.get(cal) + if prev is None or ts > prev["ts"]: + by_calendar[cal] = {"ts": ts, "fields": to_panel_fields(d, age)} + + missing = [] + d = CYCLE_START + while d <= CYCLE_END: + if d not in by_calendar: + missing.append(d) + d += timedelta(days=1) + + print(f"snapshots in window: {in_window}") + print(f"unique dates: {len(by_calendar)}/49, missing: {len(missing)}") + if missing: + print(f"missing: {[str(x) for x in missing]}") + + print( + f"\n{'date':>10} {'age':>3} {'wind':>6} {'hum%':>6} {'avgT':>6} {'expT':>6} {'water':>8}" + ) + d = CYCLE_START + while d <= CYCLE_END: + e = by_calendar.get(d) + age = (d - CYCLE_START).days + 1 + if e: + f = e["fields"] + print( + f"{d} {age:3d} {f['wind_speed']:6.2f} {f['humidity']:6.1f} " + f"{f['average_temperature']:6.1f} {f['experience_temperature']:6.1f} " + f"{f['water_total']:8.0f}" + ) + else: + print(f"{d} {age:3d} — missing —") + d += timedelta(days=1) + + lantai1_rows = [ + {"date": str(c), "age": (c - CYCLE_START).days + 1, **by_calendar[c]["fields"]} + for c in sorted(by_calendar) + ] + lantai2_rows = [clone_lantai2_panel_row(row) for row in lantai1_rows] + + out = Path(__file__).resolve().parent / "iot_panel_cycle_extract.json" + out.write_text( + json.dumps( + { + "cycle_start": str(CYCLE_START), + "cycle_end": str(CYCLE_END), + "experience_temperature": ( + "avg_temp - (wind_speed * chill_factor - (humidity-70)/5); " + "wind_speed is sensor m/s not fan count" + ), + "flocks": [ + { + "name": "Lantai 1", + "iot_flock_id": LANTAI_1_IOT_FLOCK_ID, + "source": "api", + "rows": lantai1_rows, + }, + { + "name": "Lantai 2", + "iot_flock_id": LANTAI_2_IOT_FLOCK_ID, + "source": "cloned_from_lantai_1", + "adjust": LANTAI_2_ADJUST, + "rows": lantai2_rows, + }, + ], + }, + indent=2, + ), + encoding="utf-8", + ) + print(f"\nWrote {out} ({len(lantai1_rows)} Lantai 1 + {len(lantai2_rows)} Lantai 2)") + + +if __name__ == "__main__": + main() diff --git a/scripts/iot_panel_10min_extract.json b/scripts/iot_panel_10min_extract.json new file mode 100644 index 0000000..6d9792a --- /dev/null +++ b/scripts/iot_panel_10min_extract.json @@ -0,0 +1,74984 @@ +{ + "flock_id": "686df69f407b21002da8750c", + "cycle_start": "2026-05-22", + "cycle_end": "2026-07-09", + "count": 6816, + "rows": [ + { + "timestamp": "2026-05-22T00:00:07.656071+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1029.0, + "average_temperature": 28.4667, + "experience_temperature": 14.4667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T00:10:05.968597+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1043.0, + "average_temperature": 28.4333, + "experience_temperature": 14.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T00:20:06.331712+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1057.0, + "average_temperature": 28.3667, + "experience_temperature": 14.3667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T00:30:06.004120+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1070.0, + "average_temperature": 28.4, + "experience_temperature": 14.4, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T00:40:06.490314+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1083.0, + "average_temperature": 28.3667, + "experience_temperature": 14.3667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T00:50:06.254177+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1096.0, + "average_temperature": 28.3333, + "experience_temperature": 14.3333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T01:10:06.837505+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 28.2, + "experience_temperature": 14.2, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T01:20:06.702101+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 28.1333, + "experience_temperature": 14.1333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T01:30:06.168151+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 28.0667, + "experience_temperature": 14.0667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T01:40:06.640352+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 28.0333, + "experience_temperature": 14.0333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T01:50:06.681058+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.9333, + "experience_temperature": 13.9333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:00:06.527370+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.8667, + "experience_temperature": 13.8667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:10:07.514360+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.7667, + "experience_temperature": 13.7667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:20:05.761239+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.7, + "experience_temperature": 13.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:30:06.310750+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.6667, + "experience_temperature": 13.6667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:40:05.850716+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.6, + "experience_temperature": 13.6, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T02:50:06.112378+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.5333, + "experience_temperature": 13.5333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:00:06.138251+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.4667, + "experience_temperature": 13.4667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:10:05.546675+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.4, + "experience_temperature": 13.4, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:20:05.706039+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.4, + "experience_temperature": 13.4, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:30:05.686939+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.3333, + "experience_temperature": 13.3333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:40:05.995274+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 27.8333, + "experience_temperature": 13.8333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T03:50:06.035349+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 35.0667, + "experience_temperature": 21.0667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:00:05.811899+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 37.3667, + "experience_temperature": 23.3667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:10:05.877025+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.7, + "experience_temperature": 24.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:20:07.100102+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.6333, + "experience_temperature": 24.6333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:30:06.068515+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.8, + "experience_temperature": 24.8, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:40:06.530616+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.7, + "experience_temperature": 24.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T04:50:06.191342+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.7667, + "experience_temperature": 24.7667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:00:05.974367+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.7333, + "experience_temperature": 24.7333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:10:05.986198+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.8, + "experience_temperature": 24.8, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:20:06.280011+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 38.5667, + "experience_temperature": 24.5667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:30:06.661933+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 36.9667, + "experience_temperature": 22.9667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:40:05.804036+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 34.9667, + "experience_temperature": 20.9667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T05:50:06.672522+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:00:06.095393+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 35.0667, + "experience_temperature": 21.0667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:10:06.725648+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 35.5333, + "experience_temperature": 21.5333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:20:06.287520+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:30:06.775226+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:40:05.787942+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.7333, + "experience_temperature": 25.7333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T06:50:05.940310+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.2667, + "experience_temperature": 25.2667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:00:06.714269+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.0333, + "experience_temperature": 25.0333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:10:06.246300+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.2667, + "experience_temperature": 25.2667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:20:07.935371+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.4, + "experience_temperature": 25.4, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:30:06.000830+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 39.4333, + "experience_temperature": 25.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:40:06.173860+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 41.0, + "experience_temperature": 27.0, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T07:50:06.552044+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 44.4333, + "experience_temperature": 30.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:00:07.131575+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1104.0, + "average_temperature": 44.4333, + "experience_temperature": 30.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:10:07.068573+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.9667, + "experience_temperature": 21.9667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:20:06.376641+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 36.1333, + "experience_temperature": 22.1333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:30:06.386161+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.7, + "experience_temperature": 21.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:40:07.647274+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.7, + "experience_temperature": 21.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T08:50:06.190591+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:00:07.911503+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.4, + "experience_temperature": 21.4, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:10:07.857045+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:20:06.568111+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1132.0, + "average_temperature": 35.7333, + "experience_temperature": 21.7533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:30:06.521070+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 35.8667, + "experience_temperature": 21.8667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:40:06.506760+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1132.0, + "average_temperature": 36.3, + "experience_temperature": 22.32, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T09:50:06.757909+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 36.3333, + "experience_temperature": 22.3333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:00:06.819607+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1132.0, + "average_temperature": 36.6, + "experience_temperature": 22.6, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:10:06.309495+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1141.0, + "average_temperature": 36.5, + "experience_temperature": 22.52, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:20:06.429408+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1152.0, + "average_temperature": 36.5, + "experience_temperature": 22.52, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:30:06.063531+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1161.0, + "average_temperature": 36.7333, + "experience_temperature": 22.7533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:40:06.558742+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1170.0, + "average_temperature": 36.6667, + "experience_temperature": 22.6867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T10:50:07.024396+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1177.0, + "average_temperature": 36.9, + "experience_temperature": 22.92, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:00:06.882698+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1185.0, + "average_temperature": 37.3667, + "experience_temperature": 23.3667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:10:07.042715+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1194.0, + "average_temperature": 36.7667, + "experience_temperature": 22.7867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:20:06.540428+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1203.0, + "average_temperature": 37.4333, + "experience_temperature": 23.4533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:30:06.720800+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1207.0, + "average_temperature": 36.6, + "experience_temperature": 22.6, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:40:06.721004+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1216.0, + "average_temperature": 37.4667, + "experience_temperature": 23.4667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T11:50:06.804273+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1225.0, + "average_temperature": 36.8333, + "experience_temperature": 22.8333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:00:06.227026+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1230.0, + "average_temperature": 36.6333, + "experience_temperature": 22.6533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:10:05.904401+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1239.0, + "average_temperature": 36.4667, + "experience_temperature": 22.4667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:20:07.400804+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1246.0, + "average_temperature": 36.8667, + "experience_temperature": 22.8667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:30:08.072515+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1249.0, + "average_temperature": 36.4333, + "experience_temperature": 22.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:40:07.977172+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1257.0, + "average_temperature": 36.5333, + "experience_temperature": 22.5333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T12:50:07.747096+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1260.0, + "average_temperature": 36.6667, + "experience_temperature": 22.6667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:00:06.907055+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1270.0, + "average_temperature": 36.5333, + "experience_temperature": 22.5533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:10:06.771691+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1273.0, + "average_temperature": 36.5667, + "experience_temperature": 22.5867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:20:06.500594+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1282.0, + "average_temperature": 36.6, + "experience_temperature": 22.6, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:30:07.104260+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1285.0, + "average_temperature": 36.3333, + "experience_temperature": 22.3533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:40:06.407783+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1287.0, + "average_temperature": 36.4333, + "experience_temperature": 22.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T13:50:19.327818+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1287.0, + "average_temperature": 36.4333, + "experience_temperature": 22.4333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T14:10:08.617137+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1308.0, + "average_temperature": 36.5667, + "experience_temperature": 22.5867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T14:20:06.857193+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1312.0, + "average_temperature": 36.5, + "experience_temperature": 22.52, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T14:30:06.980610+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1319.0, + "average_temperature": 36.7, + "experience_temperature": 22.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T14:40:06.699624+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1325.0, + "average_temperature": 36.7, + "experience_temperature": 22.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T14:50:06.916692+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1329.0, + "average_temperature": 36.7, + "experience_temperature": 22.72, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T15:10:06.779186+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1337.0, + "average_temperature": 36.3333, + "experience_temperature": 22.3533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T15:20:09.142813+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1342.0, + "average_temperature": 36.0667, + "experience_temperature": 22.0867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T15:30:07.938481+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1347.0, + "average_temperature": 36.0, + "experience_temperature": 22.02, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T15:40:09.304576+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1355.0, + "average_temperature": 36.1333, + "experience_temperature": 22.1533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T15:50:07.592315+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1358.0, + "average_temperature": 36.1333, + "experience_temperature": 22.1333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T16:10:07.009790+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1366.0, + "average_temperature": 35.7333, + "experience_temperature": 21.7333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T16:20:06.628412+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1368.0, + "average_temperature": 35.6667, + "experience_temperature": 21.6867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T16:30:08.247446+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1371.0, + "average_temperature": 35.3667, + "experience_temperature": 21.3867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T16:40:08.298889+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1375.0, + "average_temperature": 35.1, + "experience_temperature": 21.1, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T16:50:06.852187+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1378.0, + "average_temperature": 34.9, + "experience_temperature": 20.9, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T17:10:06.374140+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1379.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T17:20:06.928738+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1385.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T17:30:07.073943+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1390.0, + "average_temperature": 34.3, + "experience_temperature": 20.32, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T17:40:06.736574+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1390.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T17:50:08.069130+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1396.0, + "average_temperature": 35.2, + "experience_temperature": 21.22, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:00:06.871219+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1401.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:10:07.104490+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1401.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:20:06.133170+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1404.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:30:09.072180+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1409.0, + "average_temperature": 34.8, + "experience_temperature": 20.82, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:40:09.204823+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1417.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T18:50:05.976653+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1426.0, + "average_temperature": 34.3667, + "experience_temperature": 20.3867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:00:06.036474+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1431.0, + "average_temperature": 34.0667, + "experience_temperature": 20.0867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:10:06.104857+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1442.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:20:05.948696+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1451.0, + "average_temperature": 35.0667, + "experience_temperature": 21.0867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:30:06.401982+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1461.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:40:06.280274+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1466.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T19:50:06.054173+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1474.0, + "average_temperature": 35.0, + "experience_temperature": 21.0, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:00:06.427491+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1483.0, + "average_temperature": 34.5, + "experience_temperature": 20.52, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:10:06.866024+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1492.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:20:06.545788+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1496.0, + "average_temperature": 34.7, + "experience_temperature": 20.72, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:30:05.874385+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1506.0, + "average_temperature": 34.7, + "experience_temperature": 20.7, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:40:06.799093+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1515.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T20:50:06.439172+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1523.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:00:07.117266+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1533.0, + "average_temperature": 34.8667, + "experience_temperature": 20.8667, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:10:05.965543+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1537.0, + "average_temperature": 34.3, + "experience_temperature": 20.3, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:20:08.030939+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1544.0, + "average_temperature": 34.3, + "experience_temperature": 20.32, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:30:06.834686+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1552.0, + "average_temperature": 34.8, + "experience_temperature": 20.82, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:40:07.027617+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1563.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T21:50:06.022283+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1568.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:00:06.193389+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1575.0, + "average_temperature": 34.8667, + "experience_temperature": 20.8867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:10:06.486634+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1581.0, + "average_temperature": 34.1, + "experience_temperature": 20.12, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:20:06.373582+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1590.0, + "average_temperature": 35.0, + "experience_temperature": 21.0, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:30:07.532540+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1600.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:40:07.692525+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1609.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T22:50:06.753429+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1617.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:00:06.322366+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1622.0, + "average_temperature": 34.0, + "experience_temperature": 20.0, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:10:07.065454+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1636.0, + "average_temperature": 35.0, + "experience_temperature": 21.02, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:20:05.860633+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1641.0, + "average_temperature": 34.3, + "experience_temperature": 20.3, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:30:07.887137+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1649.0, + "average_temperature": 34.3667, + "experience_temperature": 20.3867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:40:07.083944+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1658.0, + "average_temperature": 34.8, + "experience_temperature": 20.82, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-22T23:50:07.242600+07:00", + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1667.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 8.0 + }, + { + "timestamp": "2026-05-23T00:00:06.178317+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1672.0, + "average_temperature": 34.9, + "experience_temperature": 20.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T00:10:07.996132+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1680.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T00:20:06.440241+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1686.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T00:30:06.191633+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1686.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T00:40:06.016825+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1700.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T00:50:06.150090+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1709.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:00:08.093745+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1715.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:10:05.894771+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1724.0, + "average_temperature": 34.7333, + "experience_temperature": 20.7533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:20:06.295862+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1733.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:30:06.365497+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1741.0, + "average_temperature": 34.7, + "experience_temperature": 20.7, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:40:06.603141+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1749.0, + "average_temperature": 34.3667, + "experience_temperature": 20.3867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T01:50:07.350618+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1754.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:00:08.967379+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1764.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:10:05.936442+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1769.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:20:06.201119+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1779.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:30:05.824299+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1788.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:40:05.805006+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1798.0, + "average_temperature": 34.7333, + "experience_temperature": 20.7533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T02:50:06.547344+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1803.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:00:06.511493+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1812.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:10:05.899251+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1821.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:20:06.779918+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1827.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:30:06.058648+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1836.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:40:06.769402+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1847.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T03:50:06.260357+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1856.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:00:05.993300+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1860.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:10:06.932986+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1870.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:20:06.802974+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1879.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:30:06.102538+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1885.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:40:06.714911+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1893.0, + "average_temperature": 34.7333, + "experience_temperature": 20.7333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T04:50:06.040503+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1904.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:00:06.839285+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1905.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:10:06.285644+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1920.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:20:06.645126+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1925.0, + "average_temperature": 34.5, + "experience_temperature": 20.5, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:30:08.236769+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1936.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:40:06.429156+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1948.0, + "average_temperature": 34.7333, + "experience_temperature": 20.7533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T05:50:07.178613+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1953.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:00:06.431828+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1963.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:10:06.535172+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1971.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:20:06.585140+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1976.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:30:06.591249+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1986.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:40:05.638769+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1994.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T06:50:06.420987+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2004.0, + "average_temperature": 33.7667, + "experience_temperature": 19.7867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:00:08.964997+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2010.0, + "average_temperature": 34.5667, + "experience_temperature": 20.5867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:10:06.059300+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2019.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:20:06.920819+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2025.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:30:06.532918+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2035.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:40:06.579222+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2045.0, + "average_temperature": 34.5667, + "experience_temperature": 20.5667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T07:50:05.963886+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2051.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:00:07.714200+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2061.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:10:06.280292+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2071.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:20:06.308903+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2079.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:30:06.027052+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2089.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:40:07.134850+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2096.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T08:50:06.615699+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2104.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:00:08.183059+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2109.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:10:07.000277+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2122.0, + "average_temperature": 34.9, + "experience_temperature": 20.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:20:07.309640+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2127.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:30:09.764496+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2136.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:40:07.463769+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2145.0, + "average_temperature": 34.5, + "experience_temperature": 20.5, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T09:50:06.373474+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2156.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:00:07.116365+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2160.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:10:06.532839+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2170.0, + "average_temperature": 34.9, + "experience_temperature": 20.9, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:20:08.037729+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2180.0, + "average_temperature": 34.9333, + "experience_temperature": 20.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:30:07.653801+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2191.0, + "average_temperature": 34.9667, + "experience_temperature": 20.9667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:40:07.137937+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2200.0, + "average_temperature": 35.2333, + "experience_temperature": 21.2333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T10:50:06.699278+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2210.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:00:07.914946+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2218.0, + "average_temperature": 35.5667, + "experience_temperature": 21.5667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:10:07.089866+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2224.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:20:07.807504+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2233.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:30:07.221671+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2243.0, + "average_temperature": 35.7667, + "experience_temperature": 21.7667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:40:08.258307+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2252.0, + "average_temperature": 35.8, + "experience_temperature": 21.8, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T11:50:07.025764+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2260.0, + "average_temperature": 35.8, + "experience_temperature": 21.82, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:00:06.861129+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2265.0, + "average_temperature": 35.6, + "experience_temperature": 21.6, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:10:07.028920+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2274.0, + "average_temperature": 35.5667, + "experience_temperature": 21.5667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:20:07.317494+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2284.0, + "average_temperature": 35.7, + "experience_temperature": 21.7, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:30:08.429420+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2295.0, + "average_temperature": 35.9, + "experience_temperature": 21.9, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:40:06.908685+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2305.0, + "average_temperature": 35.9667, + "experience_temperature": 21.9667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T12:50:07.090354+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2315.0, + "average_temperature": 35.8667, + "experience_temperature": 21.8667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:00:05.605703+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2324.0, + "average_temperature": 35.8333, + "experience_temperature": 21.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:10:06.284512+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2331.0, + "average_temperature": 35.8333, + "experience_temperature": 21.8333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:20:06.177638+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2341.0, + "average_temperature": 35.9333, + "experience_temperature": 21.9333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:30:05.798350+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2352.0, + "average_temperature": 35.9333, + "experience_temperature": 21.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:40:06.561878+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2357.0, + "average_temperature": 35.9333, + "experience_temperature": 21.9333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T13:50:06.139013+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2369.0, + "average_temperature": 35.8, + "experience_temperature": 21.82, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T14:10:06.541699+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2385.0, + "average_temperature": 35.9, + "experience_temperature": 21.9, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T14:20:06.500686+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2396.0, + "average_temperature": 35.8333, + "experience_temperature": 21.8333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T14:30:06.263545+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2405.0, + "average_temperature": 35.9, + "experience_temperature": 21.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T14:40:06.034251+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2412.0, + "average_temperature": 35.9333, + "experience_temperature": 21.9333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T14:50:05.950683+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2423.0, + "average_temperature": 35.8333, + "experience_temperature": 21.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T15:10:06.612826+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2434.0, + "average_temperature": 36.0, + "experience_temperature": 22.0, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T15:20:06.092340+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2442.0, + "average_temperature": 35.3333, + "experience_temperature": 21.3533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T15:30:05.594387+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2458.0, + "average_temperature": 35.3333, + "experience_temperature": 21.3333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T15:40:05.868260+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2464.0, + "average_temperature": 35.5, + "experience_temperature": 21.52, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T15:50:05.836003+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2475.0, + "average_temperature": 35.4, + "experience_temperature": 21.42, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T16:10:06.905190+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2490.0, + "average_temperature": 35.0333, + "experience_temperature": 21.0333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T16:20:07.572158+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2494.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T16:30:05.816311+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2497.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T16:40:05.504806+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2499.0, + "average_temperature": 34.3, + "experience_temperature": 20.3, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T16:50:07.688695+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2509.0, + "average_temperature": 35.2, + "experience_temperature": 21.22, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T17:10:06.634775+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6.0, + "average_temperature": 34.2667, + "experience_temperature": 20.2867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T17:20:06.862532+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 10.0, + "average_temperature": 34.0333, + "experience_temperature": 20.0333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T17:30:05.778689+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 15.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T17:40:06.986263+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 20.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T17:50:05.834063+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 31.0, + "average_temperature": 34.3, + "experience_temperature": 20.32, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:00:06.114255+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 38.0, + "average_temperature": 34.1, + "experience_temperature": 20.1, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:10:06.736359+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 49.0, + "average_temperature": 33.5667, + "experience_temperature": 19.5867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:20:05.704914+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 55.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:30:05.788735+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 67.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:40:05.655702+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 72.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T18:50:06.630224+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 78.0, + "average_temperature": 34.5, + "experience_temperature": 20.5, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:00:07.171026+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 90.0, + "average_temperature": 33.9, + "experience_temperature": 19.9, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:10:05.944134+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 96.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:20:07.362616+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 104.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:30:06.483901+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 108.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:40:06.417448+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 114.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T19:50:06.060121+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 123.0, + "average_temperature": 33.8333, + "experience_temperature": 19.8333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:00:07.227904+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 129.0, + "average_temperature": 33.3, + "experience_temperature": 19.32, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:10:06.686614+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 135.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:20:06.997740+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 144.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:30:05.961329+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 149.0, + "average_temperature": 33.9, + "experience_temperature": 19.9, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:40:06.118382+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 160.0, + "average_temperature": 34.3, + "experience_temperature": 20.3, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T20:50:06.022857+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 165.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:00:06.761147+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 169.0, + "average_temperature": 34.5, + "experience_temperature": 20.52, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:10:07.333797+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 181.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:20:06.463220+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 186.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:30:06.477946+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 198.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:40:06.555141+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 203.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T21:50:08.466466+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 214.0, + "average_temperature": 34.6, + "experience_temperature": 20.6, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:00:07.081843+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 218.0, + "average_temperature": 33.7333, + "experience_temperature": 19.7533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:10:06.753029+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 227.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:20:07.310761+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 237.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:30:06.098708+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 246.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:40:06.315701+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 250.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T22:50:06.321203+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 262.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:00:06.671434+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 267.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5533, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:10:07.101415+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 271.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:20:07.231848+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 277.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:30:07.883288+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 281.0, + "average_temperature": 34.3667, + "experience_temperature": 20.3867, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:40:06.651068+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 281.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6667, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-23T23:50:06.813789+07:00", + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 286.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 7.8333 + }, + { + "timestamp": "2026-05-24T00:00:07.474011+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 292.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T00:10:07.403578+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 292.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T00:20:07.143327+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 298.0, + "average_temperature": 34.3, + "experience_temperature": 20.32, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T00:30:06.380872+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 308.0, + "average_temperature": 33.5667, + "experience_temperature": 19.5667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T00:40:07.174336+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 313.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T00:50:06.522433+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 322.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:00:07.779713+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 333.0, + "average_temperature": 33.4, + "experience_temperature": 19.42, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:10:06.555325+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 343.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:20:08.485786+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 353.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:30:06.330937+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 362.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:40:06.678344+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 368.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T01:50:05.932852+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 378.0, + "average_temperature": 34.2, + "experience_temperature": 20.2, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:00:06.341459+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 388.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:10:06.438411+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 394.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:20:07.180379+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 405.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:30:06.639396+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 410.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:40:06.892767+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 418.0, + "average_temperature": 34.3, + "experience_temperature": 20.3, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T02:50:07.823892+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 428.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:00:06.952905+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 434.0, + "average_temperature": 34.2, + "experience_temperature": 20.22, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:10:07.634291+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 445.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:20:06.327084+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 449.0, + "average_temperature": 33.3, + "experience_temperature": 19.32, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:30:06.549905+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 457.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:40:08.172929+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 468.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T03:50:06.322765+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 472.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:00:06.639490+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 478.0, + "average_temperature": 33.1333, + "experience_temperature": 19.1533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:10:06.348946+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 478.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:20:06.359171+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 483.0, + "average_temperature": 33.4667, + "experience_temperature": 19.4867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:30:07.148603+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 488.0, + "average_temperature": 33.7333, + "experience_temperature": 19.7533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:40:06.815679+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 488.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T04:50:06.332181+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 494.0, + "average_temperature": 33.5667, + "experience_temperature": 19.5667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:00:06.428997+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 499.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:10:07.503801+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 505.0, + "average_temperature": 33.2667, + "experience_temperature": 19.2867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:20:06.751220+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 510.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:30:07.031125+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 520.0, + "average_temperature": 33.1333, + "experience_temperature": 19.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:40:07.054778+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 531.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T05:50:06.435082+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 535.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:00:06.852349+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 541.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:10:07.541040+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 550.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:20:06.923350+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 555.0, + "average_temperature": 33.4, + "experience_temperature": 19.42, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:30:07.448086+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 561.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:40:05.835930+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 572.0, + "average_temperature": 33.4, + "experience_temperature": 19.4, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T06:50:05.330017+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 577.0, + "average_temperature": 34.0667, + "experience_temperature": 20.0867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:00:06.115264+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 582.0, + "average_temperature": 33.6, + "experience_temperature": 19.6, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:10:05.524790+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 590.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:20:05.892000+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 595.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:30:06.247300+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 606.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:40:05.500065+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 612.0, + "average_temperature": 34.1, + "experience_temperature": 20.12, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T07:50:05.374475+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 621.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:00:06.470807+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 627.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:10:05.890252+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 627.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:20:06.559353+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 642.0, + "average_temperature": 34.9667, + "experience_temperature": 20.9867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:30:06.240388+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 651.0, + "average_temperature": 35.1667, + "experience_temperature": 21.1867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:40:06.342215+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 655.0, + "average_temperature": 35.1333, + "experience_temperature": 21.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T08:50:05.925799+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 655.0, + "average_temperature": 35.1333, + "experience_temperature": 21.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:00:05.725856+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 667.0, + "average_temperature": 35.2667, + "experience_temperature": 21.2667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:10:05.386503+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 667.0, + "average_temperature": 35.2667, + "experience_temperature": 21.2667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:20:06.292888+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 683.0, + "average_temperature": 35.4667, + "experience_temperature": 21.4867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:30:05.708401+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 688.0, + "average_temperature": 35.5, + "experience_temperature": 21.52, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:40:05.870421+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 692.0, + "average_temperature": 35.2667, + "experience_temperature": 21.2867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T09:50:05.576016+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 700.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:00:08.991582+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 702.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:10:05.942021+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 714.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:20:06.047953+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 719.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:30:05.658951+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 724.0, + "average_temperature": 36.1, + "experience_temperature": 22.12, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:40:06.403362+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 731.0, + "average_temperature": 35.3, + "experience_temperature": 21.3, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T10:50:06.763269+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 736.0, + "average_temperature": 35.4, + "experience_temperature": 21.42, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:00:06.494929+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 746.0, + "average_temperature": 35.3333, + "experience_temperature": 21.3533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:10:05.984585+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 750.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:20:08.292085+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 754.0, + "average_temperature": 36.1333, + "experience_temperature": 22.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:30:06.671238+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 768.0, + "average_temperature": 35.1667, + "experience_temperature": 21.1867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:40:06.240669+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 770.0, + "average_temperature": 35.2, + "experience_temperature": 21.2, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T11:50:07.328898+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 798.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:00:07.098124+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 822.0, + "average_temperature": 36.2333, + "experience_temperature": 22.2333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:10:06.848628+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 846.0, + "average_temperature": 35.1, + "experience_temperature": 21.1, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:20:06.633214+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 862.0, + "average_temperature": 34.9333, + "experience_temperature": 20.9333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:30:06.927270+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 881.0, + "average_temperature": 34.9667, + "experience_temperature": 20.9667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:40:06.799122+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 896.0, + "average_temperature": 35.6333, + "experience_temperature": 21.6533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T12:50:06.655657+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 905.0, + "average_temperature": 35.0333, + "experience_temperature": 21.0533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:00:06.615891+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 915.0, + "average_temperature": 34.8667, + "experience_temperature": 20.8867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:10:09.431174+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 930.0, + "average_temperature": 34.6, + "experience_temperature": 20.6, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:20:07.120636+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 940.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:30:07.964964+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 950.0, + "average_temperature": 33.9667, + "experience_temperature": 19.9867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:40:07.022762+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 960.0, + "average_temperature": 34.0333, + "experience_temperature": 20.0533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T13:50:06.799571+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 970.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T14:10:07.136770+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 990.0, + "average_temperature": 33.2, + "experience_temperature": 19.22, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T14:20:06.705967+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 999.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T14:30:06.611423+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1009.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T14:40:06.630360+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1023.0, + "average_temperature": 33.4, + "experience_temperature": 19.42, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T14:50:06.803583+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1033.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T15:10:06.994221+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1061.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T15:20:06.941145+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1112.0, + "average_temperature": 33.2, + "experience_temperature": 19.22, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T15:30:06.501082+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1183.0, + "average_temperature": 33.4, + "experience_temperature": 19.42, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T15:40:06.551184+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1208.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T15:50:07.132043+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1237.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T16:10:07.175885+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1327.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T16:20:06.728345+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1375.0, + "average_temperature": 33.3, + "experience_temperature": 19.32, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T16:30:07.489371+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1427.0, + "average_temperature": 33.0667, + "experience_temperature": 19.0867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T16:40:05.828223+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1468.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T16:50:06.234717+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1468.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T17:10:05.328374+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1603.0, + "average_temperature": 32.3, + "experience_temperature": 18.32, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T17:20:05.813600+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1645.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T17:30:05.447444+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1682.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T17:40:06.258657+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1724.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T17:50:05.608487+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1767.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:00:05.927990+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1803.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:10:07.382791+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1848.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:20:07.095713+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1883.0, + "average_temperature": 33.1667, + "experience_temperature": 19.1667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:30:06.488090+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 1921.0, + "average_temperature": 33.8, + "experience_temperature": 19.8, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:40:06.748915+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1964.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T18:50:06.392870+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2001.0, + "average_temperature": 32.9, + "experience_temperature": 18.92, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:00:07.093311+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2044.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:10:06.689187+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2087.0, + "average_temperature": 33.2, + "experience_temperature": 19.22, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:20:07.134683+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2125.0, + "average_temperature": 33.7667, + "experience_temperature": 19.7867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:30:06.790599+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2172.0, + "average_temperature": 33.5667, + "experience_temperature": 19.5667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:40:07.822103+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2207.0, + "average_temperature": 32.8, + "experience_temperature": 18.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T19:50:06.317768+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2252.0, + "average_temperature": 33.9667, + "experience_temperature": 19.9867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:00:07.264922+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2294.0, + "average_temperature": 33.0333, + "experience_temperature": 19.0533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:10:08.489796+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2336.0, + "average_temperature": 34.0333, + "experience_temperature": 20.0533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:20:06.740134+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2401.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:30:06.784703+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2460.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:40:07.855913+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2526.0, + "average_temperature": 33.7333, + "experience_temperature": 19.7533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T20:50:06.897178+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2591.0, + "average_temperature": 32.8, + "experience_temperature": 18.82, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:00:06.390058+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2657.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:10:06.671242+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2657.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:20:07.141030+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2786.0, + "average_temperature": 34.0667, + "experience_temperature": 20.0667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:30:06.702179+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2854.0, + "average_temperature": 33.2667, + "experience_temperature": 19.2667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:40:07.353441+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 2913.0, + "average_temperature": 33.9, + "experience_temperature": 19.9, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T21:50:06.505910+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 2978.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:00:07.319235+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 3042.0, + "average_temperature": 32.8, + "experience_temperature": 18.8, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:10:07.402865+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 3106.0, + "average_temperature": 34.0333, + "experience_temperature": 20.0333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:20:06.836560+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 3171.0, + "average_temperature": 33.0667, + "experience_temperature": 19.0667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:30:07.146147+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 3236.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1333, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:40:06.500307+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3298.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4533, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T22:50:06.914201+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3362.0, + "average_temperature": 33.6, + "experience_temperature": 19.62, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:00:07.074943+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3426.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:10:06.786206+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3486.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:20:06.764138+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3548.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:30:06.302523+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 3605.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8667, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:40:06.439876+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3663.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-24T23:50:06.776501+07:00", + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3720.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.6667 + }, + { + "timestamp": "2026-05-25T00:00:07.506368+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3780.0, + "average_temperature": 33.9667, + "experience_temperature": 19.9867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T00:10:07.749902+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3836.0, + "average_temperature": 33.1667, + "experience_temperature": 19.1867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T00:20:06.877385+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3899.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T00:30:06.938446+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3963.0, + "average_temperature": 33.5667, + "experience_temperature": 19.5867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T00:40:06.699388+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4025.0, + "average_temperature": 32.7667, + "experience_temperature": 18.7867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T00:50:06.758795+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4089.0, + "average_temperature": 34.0, + "experience_temperature": 20.02, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:00:07.230732+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4151.0, + "average_temperature": 32.9667, + "experience_temperature": 18.9667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:10:06.790472+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4214.0, + "average_temperature": 34.0667, + "experience_temperature": 20.0667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:20:07.205771+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4277.0, + "average_temperature": 33.3, + "experience_temperature": 19.32, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:30:06.911059+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4333.0, + "average_temperature": 33.0667, + "experience_temperature": 19.0867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:40:07.079099+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4395.0, + "average_temperature": 33.7667, + "experience_temperature": 19.7667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T01:50:07.535346+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4451.0, + "average_temperature": 32.8, + "experience_temperature": 18.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:00:06.858846+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4508.0, + "average_temperature": 33.9667, + "experience_temperature": 19.9667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:10:06.851031+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4570.0, + "average_temperature": 32.9, + "experience_temperature": 18.9, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:20:06.753722+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4626.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:30:06.852074+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4689.0, + "average_temperature": 33.0333, + "experience_temperature": 19.0533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:40:06.910575+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4745.0, + "average_temperature": 33.7333, + "experience_temperature": 19.7333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T02:50:06.139779+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4807.0, + "average_temperature": 33.0, + "experience_temperature": 19.0, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:00:06.373772+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 4864.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:10:06.622703+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4926.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:20:06.429776+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 4987.0, + "average_temperature": 33.1667, + "experience_temperature": 19.1867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:30:06.163630+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5044.0, + "average_temperature": 33.4, + "experience_temperature": 19.4, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:40:05.596478+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5105.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T03:50:05.605740+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5161.0, + "average_temperature": 33.8333, + "experience_temperature": 19.8333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:00:06.352904+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5223.0, + "average_temperature": 32.7, + "experience_temperature": 18.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:10:05.933974+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5279.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:20:06.358353+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5335.0, + "average_temperature": 32.7, + "experience_temperature": 18.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:30:05.715162+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5391.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:40:05.869414+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5446.0, + "average_temperature": 32.8, + "experience_temperature": 18.8, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T04:50:05.440198+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5502.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:00:06.614983+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5558.0, + "average_temperature": 32.9, + "experience_temperature": 18.92, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:10:05.709380+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5614.0, + "average_temperature": 33.9333, + "experience_temperature": 19.9533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:20:05.564619+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5677.0, + "average_temperature": 33.1667, + "experience_temperature": 19.1667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:30:05.756314+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5739.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:40:07.597463+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5796.0, + "average_temperature": 33.4667, + "experience_temperature": 19.4867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T05:50:07.476911+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5852.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:00:05.930444+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 5914.0, + "average_temperature": 33.7667, + "experience_temperature": 19.7867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:10:06.685270+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 5971.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:20:05.485798+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6028.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:30:07.162302+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6092.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:40:05.603268+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6152.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T06:50:06.872766+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6214.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:00:06.441939+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6271.0, + "average_temperature": 32.9, + "experience_temperature": 18.92, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:10:07.533442+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6328.0, + "average_temperature": 33.6, + "experience_temperature": 19.6, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:20:05.932496+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6384.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:30:06.425787+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6441.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:40:05.921303+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6501.0, + "average_temperature": 33.1667, + "experience_temperature": 19.1667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T07:50:06.768113+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6554.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:00:06.891026+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6616.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:10:07.217695+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6674.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:20:06.034914+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6730.0, + "average_temperature": 33.6, + "experience_temperature": 19.6, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:30:05.575144+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6730.0, + "average_temperature": 33.6, + "experience_temperature": 19.6, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:40:07.341533+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6844.0, + "average_temperature": 33.8333, + "experience_temperature": 19.8533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T08:50:08.410834+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 6900.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:00:06.582766+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6955.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:10:06.258334+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 6993.0, + "average_temperature": 34.4, + "experience_temperature": 20.4, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:20:07.962710+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7027.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:30:07.308569+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7059.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:40:07.949227+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7094.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T09:50:06.464098+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7126.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:00:07.204659+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7162.0, + "average_temperature": 34.7333, + "experience_temperature": 20.7333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:10:06.896437+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7194.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:20:07.635476+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7225.0, + "average_temperature": 34.8333, + "experience_temperature": 20.8533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:30:06.912396+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7257.0, + "average_temperature": 35.1, + "experience_temperature": 21.12, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:40:09.130354+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7294.0, + "average_temperature": 35.1333, + "experience_temperature": 21.1533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T10:50:07.753696+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7327.0, + "average_temperature": 35.4667, + "experience_temperature": 21.4867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:00:06.976918+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7359.0, + "average_temperature": 35.0667, + "experience_temperature": 21.0867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:10:06.867894+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7397.0, + "average_temperature": 35.0, + "experience_temperature": 21.02, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:20:06.322979+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7430.0, + "average_temperature": 34.7, + "experience_temperature": 20.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:30:05.896951+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7467.0, + "average_temperature": 35.3, + "experience_temperature": 21.32, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:40:06.473687+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7501.0, + "average_temperature": 35.4333, + "experience_temperature": 21.4333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T11:50:07.916248+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7534.0, + "average_temperature": 34.8, + "experience_temperature": 20.8, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:00:08.095028+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7572.0, + "average_temperature": 35.2667, + "experience_temperature": 21.2667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:10:05.828736+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7604.0, + "average_temperature": 35.4667, + "experience_temperature": 21.4667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:20:07.176255+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7641.0, + "average_temperature": 35.2, + "experience_temperature": 21.22, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:30:09.610568+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7672.0, + "average_temperature": 34.9333, + "experience_temperature": 20.9333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:40:06.177105+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7703.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T12:50:06.301682+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7735.0, + "average_temperature": 34.9, + "experience_temperature": 20.92, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:00:07.352676+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7773.0, + "average_temperature": 34.5667, + "experience_temperature": 20.5867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:10:07.326401+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7810.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:20:07.475588+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7845.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:30:07.225966+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7883.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:40:08.240662+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 7917.0, + "average_temperature": 34.6, + "experience_temperature": 20.6, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T13:50:08.417888+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 7953.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T14:10:06.967936+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8022.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T14:20:07.538182+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8022.0, + "average_temperature": 34.6333, + "experience_temperature": 20.6533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T14:30:09.249145+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8089.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T14:40:09.165778+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8126.0, + "average_temperature": 34.7667, + "experience_temperature": 20.7667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T14:50:07.382346+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8166.0, + "average_temperature": 34.6667, + "experience_temperature": 20.6867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T15:10:06.570784+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8234.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T15:20:05.853627+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8269.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T15:30:07.269539+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8305.0, + "average_temperature": 34.6, + "experience_temperature": 20.62, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T15:40:06.143315+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8342.0, + "average_temperature": 34.5333, + "experience_temperature": 20.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T15:50:08.413104+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8355.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T16:10:07.056066+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8392.0, + "average_temperature": 34.5, + "experience_temperature": 20.52, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T16:20:07.725132+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8409.0, + "average_temperature": 34.3333, + "experience_temperature": 20.3333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T16:30:06.637716+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8426.0, + "average_temperature": 34.3, + "experience_temperature": 20.32, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T16:40:05.847677+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8439.0, + "average_temperature": 34.0667, + "experience_temperature": 20.0867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T16:50:06.649002+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8456.0, + "average_temperature": 33.9667, + "experience_temperature": 19.9867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T17:10:08.232965+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8488.0, + "average_temperature": 33.6667, + "experience_temperature": 19.6867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T17:20:06.274732+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8504.0, + "average_temperature": 33.4333, + "experience_temperature": 19.4533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T17:30:06.673706+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8518.0, + "average_temperature": 33.2, + "experience_temperature": 19.22, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T17:40:06.677395+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8539.0, + "average_temperature": 33.8, + "experience_temperature": 19.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T17:50:05.938245+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8552.0, + "average_temperature": 33.1333, + "experience_temperature": 19.1533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:00:06.181588+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8570.0, + "average_temperature": 33.7, + "experience_temperature": 19.72, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:10:06.766150+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8587.0, + "average_temperature": 33.4, + "experience_temperature": 19.42, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:20:06.314766+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8600.0, + "average_temperature": 33.0333, + "experience_temperature": 19.0533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:30:06.584993+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8615.0, + "average_temperature": 32.6667, + "experience_temperature": 18.6867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:40:05.965561+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8631.0, + "average_temperature": 33.3, + "experience_temperature": 19.32, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T18:50:06.248004+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8651.0, + "average_temperature": 33.1, + "experience_temperature": 19.12, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:00:06.303377+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8666.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:10:06.654231+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8682.0, + "average_temperature": 32.5333, + "experience_temperature": 18.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:20:06.283544+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8703.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:30:07.283511+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8716.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:40:06.312808+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8733.0, + "average_temperature": 32.5333, + "experience_temperature": 18.5533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T19:50:06.407293+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8751.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:00:06.771135+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8766.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:10:06.186769+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8766.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:20:08.176217+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8796.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:30:06.867808+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8810.0, + "average_temperature": 32.7667, + "experience_temperature": 18.7867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:40:09.381446+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8824.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T20:50:05.882204+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8840.0, + "average_temperature": 33.2, + "experience_temperature": 19.2, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:00:06.614374+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 8852.0, + "average_temperature": 32.5333, + "experience_temperature": 18.5333, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:10:06.906075+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8868.0, + "average_temperature": 33.2333, + "experience_temperature": 19.2533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:20:07.461849+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8885.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:30:06.657037+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8898.0, + "average_temperature": 32.4, + "experience_temperature": 18.42, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:40:06.471743+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8909.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T21:50:06.445093+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8925.0, + "average_temperature": 32.6667, + "experience_temperature": 18.6867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:00:05.941158+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8936.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:10:06.200482+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8949.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:20:06.695436+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8962.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:30:06.520919+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8978.0, + "average_temperature": 33.2667, + "experience_temperature": 19.2867, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:40:05.933430+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 8991.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6533, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T22:50:05.913987+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9003.0, + "average_temperature": 32.8, + "experience_temperature": 18.8, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:00:05.869976+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9011.0, + "average_temperature": 32.8, + "experience_temperature": 18.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:10:05.571510+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9018.0, + "average_temperature": 32.5, + "experience_temperature": 18.52, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:20:06.643711+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9026.0, + "average_temperature": 32.8, + "experience_temperature": 18.82, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:30:06.753386+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9031.0, + "average_temperature": 32.6, + "experience_temperature": 18.62, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:40:06.405001+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9037.0, + "average_temperature": 32.9, + "experience_temperature": 18.92, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-25T23:50:07.745571+07:00", + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9045.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3667, + "chill_factor": 7.5 + }, + { + "timestamp": "2026-05-26T00:00:06.286984+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9054.0, + "average_temperature": 32.8333, + "experience_temperature": 18.8333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T00:10:05.859029+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9063.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T00:20:06.498079+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9080.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T00:30:06.279942+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9096.0, + "average_temperature": 32.4667, + "experience_temperature": 18.4867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T00:40:05.682615+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9109.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T00:50:06.360927+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9121.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:00:06.427271+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9134.0, + "average_temperature": 32.2333, + "experience_temperature": 18.2533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:10:06.519319+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9147.0, + "average_temperature": 32.6667, + "experience_temperature": 18.6867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:20:06.046739+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9161.0, + "average_temperature": 32.2667, + "experience_temperature": 18.2867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:30:06.268805+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9174.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:40:06.142619+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9183.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T01:50:06.597247+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9201.0, + "average_temperature": 32.5, + "experience_temperature": 18.52, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:00:06.734120+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9210.0, + "average_temperature": 32.5667, + "experience_temperature": 18.5667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:10:06.774305+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9223.0, + "average_temperature": 32.6333, + "experience_temperature": 18.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:20:05.833363+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9239.0, + "average_temperature": 32.4, + "experience_temperature": 18.42, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:30:06.213062+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9250.0, + "average_temperature": 32.5333, + "experience_temperature": 18.5533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:40:06.175873+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9260.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T02:50:06.201557+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9275.0, + "average_temperature": 32.6, + "experience_temperature": 18.62, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:00:06.082253+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9284.0, + "average_temperature": 32.5, + "experience_temperature": 18.52, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:10:06.140148+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9300.0, + "average_temperature": 32.8667, + "experience_temperature": 18.8667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:20:05.636723+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9314.0, + "average_temperature": 32.3, + "experience_temperature": 18.32, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:30:05.758620+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9330.0, + "average_temperature": 33.0333, + "experience_temperature": 19.0533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:40:05.946386+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9340.0, + "average_temperature": 32.4667, + "experience_temperature": 18.4867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T03:50:06.877343+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9354.0, + "average_temperature": 32.7, + "experience_temperature": 18.72, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:00:06.338267+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9363.0, + "average_temperature": 32.4667, + "experience_temperature": 18.4867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:10:05.893899+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9369.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:20:06.122576+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9373.0, + "average_temperature": 32.5, + "experience_temperature": 18.52, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:30:06.617672+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9383.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:40:05.799183+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9387.0, + "average_temperature": 32.3333, + "experience_temperature": 18.3333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T04:50:06.453413+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9392.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:00:06.440317+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9408.0, + "average_temperature": 32.5, + "experience_temperature": 18.5, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:10:05.674979+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9430.0, + "average_temperature": 32.6667, + "experience_temperature": 18.6667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:20:07.138112+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9445.0, + "average_temperature": 32.2667, + "experience_temperature": 18.2867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:30:06.355052+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9461.0, + "average_temperature": 33.1333, + "experience_temperature": 19.1533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:40:06.091420+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9481.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T05:50:06.314033+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9496.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:00:06.328611+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9511.0, + "average_temperature": 32.3, + "experience_temperature": 18.32, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:10:06.751404+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9532.0, + "average_temperature": 32.7333, + "experience_temperature": 18.7533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:20:06.220368+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9545.0, + "average_temperature": 32.2333, + "experience_temperature": 18.2533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:30:06.198391+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9562.0, + "average_temperature": 32.5333, + "experience_temperature": 18.5533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:40:06.380711+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9578.0, + "average_temperature": 32.6, + "experience_temperature": 18.6, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T06:50:06.316809+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9592.0, + "average_temperature": 32.3, + "experience_temperature": 18.3, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:00:06.714035+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9608.0, + "average_temperature": 33.0333, + "experience_temperature": 19.0533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:10:06.327163+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9624.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:20:07.068912+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9644.0, + "average_temperature": 33.0667, + "experience_temperature": 19.0667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:30:06.142690+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9659.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:40:06.183878+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9674.0, + "average_temperature": 33.3333, + "experience_temperature": 19.3533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T07:50:07.004584+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9695.0, + "average_temperature": 33.5, + "experience_temperature": 19.52, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:00:11.949526+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9711.0, + "average_temperature": 33.5333, + "experience_temperature": 19.5533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:10:07.482144+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9731.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:20:06.339752+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9731.0, + "average_temperature": 33.6333, + "experience_temperature": 19.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:30:05.922962+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9764.0, + "average_temperature": 34.0, + "experience_temperature": 20.0, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:40:07.097697+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9780.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T08:50:06.466960+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9801.0, + "average_temperature": 33.7333, + "experience_temperature": 19.7333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:00:07.013916+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9817.0, + "average_temperature": 33.8333, + "experience_temperature": 19.8333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:10:07.055542+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9832.0, + "average_temperature": 34.0333, + "experience_temperature": 20.0533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:20:08.253978+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9854.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:30:07.109815+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9872.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:40:08.418300+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9887.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T09:50:09.899053+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9908.0, + "average_temperature": 33.9, + "experience_temperature": 19.92, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:00:14.985699+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9940.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:10:07.457898+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9956.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:20:09.660060+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 9956.0, + "average_temperature": 34.1333, + "experience_temperature": 20.1533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:30:06.875943+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 10047.0, + "average_temperature": 35.1667, + "experience_temperature": 21.1867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:40:06.936237+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 10079.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T10:50:06.796129+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 10110.0, + "average_temperature": 34.4667, + "experience_temperature": 20.4867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T11:00:08.603715+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 10123.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T11:50:06.787110+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 10123.0, + "average_temperature": 34.4333, + "experience_temperature": 20.4533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:00:07.142896+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.4, + "water_total": 10123.0, + "average_temperature": 37.7333, + "experience_temperature": 38.0133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:10:06.549310+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.4, + "water_total": 10123.0, + "average_temperature": 37.7333, + "experience_temperature": 38.0133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:20:07.591083+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.4, + "water_total": 10123.0, + "average_temperature": 37.7333, + "experience_temperature": 38.0133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:30:08.493060+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.4, + "humidity": 70.7, + "water_total": 10123.0, + "average_temperature": 36.6733, + "experience_temperature": 33.88, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:40:06.129702+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.1, + "humidity": 69.3, + "water_total": 10439.0, + "average_temperature": 35.5, + "experience_temperature": 34.6267, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T12:50:06.870176+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.4, + "humidity": 68.7, + "water_total": 10470.0, + "average_temperature": 35.6667, + "experience_temperature": 32.4733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:00:06.528646+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.4, + "humidity": 70.1, + "water_total": 10502.0, + "average_temperature": 35.8, + "experience_temperature": 32.8867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:10:06.347281+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.1, + "humidity": 71.1, + "water_total": 10526.0, + "average_temperature": 35.5, + "experience_temperature": 34.9867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:20:06.710103+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.4, + "humidity": 69.9, + "water_total": 10526.0, + "average_temperature": 35.5333, + "experience_temperature": 32.58, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:30:07.819520+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.3, + "humidity": 68.8, + "water_total": 10581.0, + "average_temperature": 35.5333, + "experience_temperature": 33.0933, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:40:06.163387+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.0, + "water_total": 10605.0, + "average_temperature": 35.4333, + "experience_temperature": 35.6333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T13:50:06.119984+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.5, + "humidity": 69.1, + "water_total": 10630.0, + "average_temperature": 35.5333, + "experience_temperature": 31.6867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T14:10:06.463004+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.8, + "water_total": 10678.0, + "average_temperature": 35.5, + "experience_temperature": 35.86, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T14:20:06.695995+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.1, + "humidity": 71.3, + "water_total": 10710.0, + "average_temperature": 35.5, + "experience_temperature": 35.0267, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T14:30:08.341087+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.5, + "water_total": 10741.0, + "average_temperature": 35.4, + "experience_temperature": 35.7, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T14:40:06.887370+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.1, + "humidity": 70.9, + "water_total": 10769.0, + "average_temperature": 35.4333, + "experience_temperature": 34.88, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T14:50:05.867125+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.1, + "humidity": 72.9, + "water_total": 10797.0, + "average_temperature": 35.3667, + "experience_temperature": 35.2133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T15:10:07.619207+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 71.8, + "water_total": 10850.0, + "average_temperature": 35.0, + "experience_temperature": 35.36, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T15:20:08.193835+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 72.9, + "water_total": 10873.0, + "average_temperature": 34.9333, + "experience_temperature": 35.5133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T15:30:06.095046+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 73.2, + "water_total": 10901.0, + "average_temperature": 34.6667, + "experience_temperature": 35.3067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T15:40:06.611031+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 73.2, + "water_total": 10901.0, + "average_temperature": 34.6667, + "experience_temperature": 35.3067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T15:50:06.773290+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 74.9, + "water_total": 10945.0, + "average_temperature": 34.3667, + "experience_temperature": 35.3467, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T16:10:07.423455+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 76.2, + "water_total": 10992.0, + "average_temperature": 34.0333, + "experience_temperature": 35.2733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T16:20:06.653351+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 75.5, + "water_total": 11013.0, + "average_temperature": 34.0667, + "experience_temperature": 35.1667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T16:30:07.433352+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 77.0, + "water_total": 11039.0, + "average_temperature": 34.1667, + "experience_temperature": 35.5667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T16:40:07.659157+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 77.1, + "water_total": 11062.0, + "average_temperature": 33.9667, + "experience_temperature": 35.3867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T16:50:06.518347+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 77.6, + "water_total": 11090.0, + "average_temperature": 34.0667, + "experience_temperature": 35.5867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T17:10:06.414307+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 75.7, + "water_total": 17.0, + "average_temperature": 33.9667, + "experience_temperature": 35.1067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T17:20:06.148983+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 76.4, + "water_total": 41.0, + "average_temperature": 33.8, + "experience_temperature": 35.08, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T17:30:06.048873+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 77.1, + "water_total": 64.0, + "average_temperature": 33.8667, + "experience_temperature": 35.2867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T17:40:07.803721+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 77.7, + "water_total": 80.0, + "average_temperature": 33.5333, + "experience_temperature": 35.0733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T17:50:05.995785+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 108.0, + "average_temperature": 33.5, + "experience_temperature": 35.58, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:00:06.090898+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 108.0, + "average_temperature": 33.5, + "experience_temperature": 35.58, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:10:06.353123+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 81.3, + "water_total": 149.0, + "average_temperature": 33.0, + "experience_temperature": 35.26, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:20:05.860686+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 166.0, + "average_temperature": 32.9667, + "experience_temperature": 35.2867, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:30:05.593998+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 196.0, + "average_temperature": 33.0, + "experience_temperature": 35.62, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:40:05.925673+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 212.0, + "average_temperature": 32.5333, + "experience_temperature": 35.0933, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T18:50:07.018467+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 236.0, + "average_temperature": 32.5667, + "experience_temperature": 35.4467, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:00:06.541957+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 257.0, + "average_temperature": 32.6, + "experience_temperature": 35.52, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:10:06.339803+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 282.0, + "average_temperature": 32.7, + "experience_temperature": 35.64, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:20:05.753038+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 282.0, + "average_temperature": 32.7, + "experience_temperature": 35.64, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:30:06.245148+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 326.0, + "average_temperature": 32.5, + "experience_temperature": 35.5, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:40:06.685007+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.8, + "water_total": 348.0, + "average_temperature": 32.4333, + "experience_temperature": 35.5933, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T19:50:06.638436+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 364.0, + "average_temperature": 32.4, + "experience_temperature": 35.58, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:00:06.642844+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 390.0, + "average_temperature": 32.3667, + "experience_temperature": 35.2667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:10:08.314904+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 407.0, + "average_temperature": 32.1667, + "experience_temperature": 35.2067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:20:06.054458+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 424.0, + "average_temperature": 32.1333, + "experience_temperature": 35.2333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:30:05.717999+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 438.0, + "average_temperature": 32.0333, + "experience_temperature": 35.1333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:40:05.606502+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 452.0, + "average_temperature": 32.1333, + "experience_temperature": 35.3733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T20:50:06.419420+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.4, + "water_total": 475.0, + "average_temperature": 31.9667, + "experience_temperature": 35.4467, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:00:07.441496+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.7, + "water_total": 489.0, + "average_temperature": 31.8667, + "experience_temperature": 35.0067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:10:06.595979+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.7, + "water_total": 510.0, + "average_temperature": 31.8333, + "experience_temperature": 34.9733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:20:06.848906+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.8, + "water_total": 522.0, + "average_temperature": 31.7333, + "experience_temperature": 34.8933, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:30:06.722032+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.9, + "water_total": 543.0, + "average_temperature": 31.6333, + "experience_temperature": 35.0133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:40:06.167965+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.8, + "water_total": 554.0, + "average_temperature": 31.5667, + "experience_temperature": 34.7267, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T21:50:07.325284+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.0, + "water_total": 563.0, + "average_temperature": 31.5333, + "experience_temperature": 34.9333, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:00:07.668699+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.7, + "water_total": 575.0, + "average_temperature": 31.3667, + "experience_temperature": 34.7067, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:10:06.681050+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.8, + "water_total": 585.0, + "average_temperature": 31.3, + "experience_temperature": 34.66, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:20:06.646618+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.4, + "water_total": 602.0, + "average_temperature": 31.2, + "experience_temperature": 34.48, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:30:06.154736+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.1, + "water_total": 608.0, + "average_temperature": 31.2333, + "experience_temperature": 34.6533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:40:06.273312+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.0, + "water_total": 618.0, + "average_temperature": 31.1667, + "experience_temperature": 34.5667, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T22:50:06.093765+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.8, + "water_total": 628.0, + "average_temperature": 31.0333, + "experience_temperature": 34.3933, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:00:06.357211+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.4, + "water_total": 639.0, + "average_temperature": 30.9, + "experience_temperature": 34.38, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:10:06.187593+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.6, + "water_total": 647.0, + "average_temperature": 30.7333, + "experience_temperature": 34.2533, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:20:08.066162+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 654.0, + "average_temperature": 30.4667, + "experience_temperature": 33.9267, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:30:06.705902+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 89.2, + "water_total": 668.0, + "average_temperature": 30.9333, + "experience_temperature": 34.7733, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:40:05.849870+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 86.8, + "water_total": 674.0, + "average_temperature": 32.8, + "experience_temperature": 36.16, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-26T23:50:06.330112+07:00", + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 681.0, + "average_temperature": 32.7333, + "experience_temperature": 35.9133, + "chill_factor": 7.3333 + }, + { + "timestamp": "2026-05-27T00:00:06.358776+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 683.0, + "average_temperature": 32.0, + "experience_temperature": 35.0, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T00:10:06.254963+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.6, + "water_total": 688.0, + "average_temperature": 31.7667, + "experience_temperature": 35.0867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T00:20:06.225480+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.5, + "water_total": 694.0, + "average_temperature": 31.3, + "experience_temperature": 34.6, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T00:30:06.749642+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.7, + "water_total": 701.0, + "average_temperature": 31.0, + "experience_temperature": 34.34, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T00:40:05.801285+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.4, + "water_total": 710.0, + "average_temperature": 30.8, + "experience_temperature": 34.28, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T00:50:05.826071+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 89.4, + "water_total": 717.0, + "average_temperature": 31.3333, + "experience_temperature": 35.2133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:00:05.893912+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 721.0, + "average_temperature": 31.6333, + "experience_temperature": 34.8733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:10:06.200541+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 733.0, + "average_temperature": 31.1333, + "experience_temperature": 34.2533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:20:06.470308+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 737.0, + "average_temperature": 30.8, + "experience_temperature": 33.9, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:30:06.272904+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 744.0, + "average_temperature": 30.6667, + "experience_temperature": 33.8867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:40:06.149306+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.6, + "water_total": 747.0, + "average_temperature": 30.5667, + "experience_temperature": 33.8867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T01:50:07.008763+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.8, + "water_total": 749.0, + "average_temperature": 32.1667, + "experience_temperature": 35.7267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:00:05.992248+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.8, + "water_total": 760.0, + "average_temperature": 32.4, + "experience_temperature": 35.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:10:07.153808+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.5, + "water_total": 770.0, + "average_temperature": 31.9333, + "experience_temperature": 35.2333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:20:05.995105+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 778.0, + "average_temperature": 31.6333, + "experience_temperature": 34.8333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:30:06.603877+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.3, + "water_total": 779.0, + "average_temperature": 31.2333, + "experience_temperature": 34.4933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:40:06.185686+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 784.0, + "average_temperature": 31.3, + "experience_temperature": 34.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T02:50:05.690482+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 789.0, + "average_temperature": 31.0, + "experience_temperature": 34.22, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:00:06.740488+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 89.2, + "water_total": 793.0, + "average_temperature": 31.7333, + "experience_temperature": 35.5733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:10:05.638661+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 798.0, + "average_temperature": 32.0333, + "experience_temperature": 35.2333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:20:06.207495+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.3, + "water_total": 803.0, + "average_temperature": 31.5, + "experience_temperature": 34.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:30:06.653363+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 806.0, + "average_temperature": 31.0, + "experience_temperature": 34.46, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:40:07.825216+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 810.0, + "average_temperature": 30.8667, + "experience_temperature": 34.3267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T03:50:06.970911+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 89.3, + "water_total": 812.0, + "average_temperature": 31.4333, + "experience_temperature": 35.2933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:00:06.165990+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 88.3, + "water_total": 816.0, + "average_temperature": 32.2, + "experience_temperature": 35.86, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:10:09.041503+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 816.0, + "average_temperature": 31.6667, + "experience_temperature": 34.9067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:20:07.631795+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 85.7, + "water_total": 818.0, + "average_temperature": 31.3667, + "experience_temperature": 34.5067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:30:06.451953+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 819.0, + "average_temperature": 31.1667, + "experience_temperature": 34.4067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:40:06.127597+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.4, + "water_total": 822.0, + "average_temperature": 31.0, + "experience_temperature": 34.28, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T04:50:06.256152+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.7, + "water_total": 825.0, + "average_temperature": 31.0, + "experience_temperature": 34.34, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:00:06.276607+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 829.0, + "average_temperature": 30.9, + "experience_temperature": 34.36, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:10:07.197729+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.1, + "water_total": 829.0, + "average_temperature": 30.5333, + "experience_temperature": 33.9533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:20:06.172678+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 89.5, + "water_total": 829.0, + "average_temperature": 31.4667, + "experience_temperature": 35.3667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:30:06.690391+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.7, + "water_total": 829.0, + "average_temperature": 32.7, + "experience_temperature": 36.04, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:40:06.651610+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 830.0, + "average_temperature": 32.1, + "experience_temperature": 35.34, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T05:50:09.002687+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.6, + "water_total": 830.0, + "average_temperature": 31.7333, + "experience_temperature": 35.0533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:00:06.547644+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 830.0, + "average_temperature": 32.7667, + "experience_temperature": 36.2267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:10:06.327882+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 834.0, + "average_temperature": 32.1667, + "experience_temperature": 34.7067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:20:06.117856+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 834.0, + "average_temperature": 32.1667, + "experience_temperature": 34.7067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:30:07.075684+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 90.0, + "water_total": 835.0, + "average_temperature": 32.4667, + "experience_temperature": 36.4667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:40:06.306003+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 835.0, + "average_temperature": 32.4333, + "experience_temperature": 35.1933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T06:50:07.334849+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 835.0, + "average_temperature": 32.0, + "experience_temperature": 35.2, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:00:06.722083+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.4, + "water_total": 835.0, + "average_temperature": 31.9667, + "experience_temperature": 35.2467, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:10:06.322745+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.5, + "water_total": 836.0, + "average_temperature": 31.9, + "experience_temperature": 35.2, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:20:06.140896+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.2, + "water_total": 838.0, + "average_temperature": 31.9333, + "experience_temperature": 35.3733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:30:06.658449+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 87.4, + "water_total": 838.0, + "average_temperature": 32.2333, + "experience_temperature": 35.7133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:40:06.138314+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 86.9, + "water_total": 840.0, + "average_temperature": 32.6, + "experience_temperature": 35.98, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T07:50:07.352128+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 845.0, + "average_temperature": 32.8, + "experience_temperature": 35.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:00:06.013418+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 845.0, + "average_temperature": 32.8, + "experience_temperature": 35.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:10:06.379288+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 865.0, + "average_temperature": 33.1, + "experience_temperature": 35.48, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:20:05.946989+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 865.0, + "average_temperature": 33.1, + "experience_temperature": 35.48, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:30:07.013206+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 915.0, + "average_temperature": 33.2667, + "experience_temperature": 35.5467, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:40:07.136960+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 951.0, + "average_temperature": 33.2, + "experience_temperature": 35.58, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T08:50:07.289851+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 979.0, + "average_temperature": 33.4, + "experience_temperature": 35.26, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:00:07.066893+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 78.6, + "water_total": 1014.0, + "average_temperature": 33.3667, + "experience_temperature": 35.0867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:10:06.437716+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 1046.0, + "average_temperature": 33.6333, + "experience_temperature": 35.3133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:20:06.536995+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 77.8, + "water_total": 1080.0, + "average_temperature": 33.7, + "experience_temperature": 35.26, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:30:06.081926+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.1, + "humidity": 76.2, + "water_total": 1104.0, + "average_temperature": 33.8, + "experience_temperature": 34.3233, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:40:06.005290+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 72.8, + "water_total": 1142.0, + "average_temperature": 33.9667, + "experience_temperature": 33.0933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T09:50:06.597545+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 74.6, + "water_total": 1184.0, + "average_temperature": 34.4667, + "experience_temperature": 35.3867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:00:06.381164+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 70.9, + "water_total": 1215.0, + "average_temperature": 33.7333, + "experience_temperature": 32.48, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:10:05.704175+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 71.6, + "water_total": 1250.0, + "average_temperature": 33.8667, + "experience_temperature": 34.1867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:20:06.902490+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 71.0, + "water_total": 1282.0, + "average_temperature": 34.3, + "experience_temperature": 34.5, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:30:07.070650+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 71.2, + "water_total": 1316.0, + "average_temperature": 34.4, + "experience_temperature": 34.64, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:40:07.055251+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 67.6, + "water_total": 1350.0, + "average_temperature": 34.3333, + "experience_temperature": 33.8533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T10:50:07.364979+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 67.2, + "water_total": 1392.0, + "average_temperature": 34.8, + "experience_temperature": 34.24, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:00:06.117320+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 66.1, + "water_total": 1434.0, + "average_temperature": 34.7667, + "experience_temperature": 33.9867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:10:08.621325+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 65.6, + "water_total": 1479.0, + "average_temperature": 35.0, + "experience_temperature": 31.97, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:20:07.590694+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.1, + "humidity": 66.8, + "water_total": 1520.0, + "average_temperature": 34.5667, + "experience_temperature": 33.21, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:30:06.736006+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.1, + "humidity": 66.8, + "water_total": 1558.0, + "average_temperature": 34.1333, + "experience_temperature": 32.7767, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:40:06.652816+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 67.4, + "water_total": 1584.0, + "average_temperature": 34.7, + "experience_temperature": 32.7467, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T11:50:07.533971+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 65.1, + "water_total": 1597.0, + "average_temperature": 34.9333, + "experience_temperature": 32.52, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:00:06.268647+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 65.1, + "water_total": 1603.0, + "average_temperature": 34.9, + "experience_temperature": 29.62, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:10:06.746491+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 65.2, + "water_total": 1606.0, + "average_temperature": 34.7667, + "experience_temperature": 29.5067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:20:06.462997+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 66.9, + "water_total": 1631.0, + "average_temperature": 34.7667, + "experience_temperature": 29.8467, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:30:06.417278+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 64.9, + "water_total": 1656.0, + "average_temperature": 34.7, + "experience_temperature": 31.53, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:40:07.753848+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.7, + "humidity": 66.1, + "water_total": 1692.0, + "average_temperature": 34.7667, + "experience_temperature": 28.97, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T12:50:06.090168+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 67.0, + "water_total": 1722.0, + "average_temperature": 34.7333, + "experience_temperature": 32.7, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:00:08.684562+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 66.7, + "water_total": 1748.0, + "average_temperature": 34.5333, + "experience_temperature": 32.44, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:10:06.495318+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 66.2, + "water_total": 1780.0, + "average_temperature": 34.5333, + "experience_temperature": 31.6233, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:20:07.656344+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 66.6, + "water_total": 1804.0, + "average_temperature": 34.7667, + "experience_temperature": 29.7867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:30:08.716121+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.7, + "humidity": 64.5, + "water_total": 1832.0, + "average_temperature": 34.8667, + "experience_temperature": 28.75, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:40:06.914929+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.5, + "humidity": 64.5, + "water_total": 1863.0, + "average_temperature": 35.2, + "experience_temperature": 30.5167, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T13:50:06.318709+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 64.6, + "water_total": 1887.0, + "average_temperature": 35.1, + "experience_temperature": 29.72, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T14:10:09.157233+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.6, + "humidity": 67.0, + "water_total": 1938.0, + "average_temperature": 34.7333, + "experience_temperature": 29.8333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T14:20:07.627630+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 67.7, + "water_total": 1968.0, + "average_temperature": 34.6333, + "experience_temperature": 32.74, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T14:30:07.889873+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.4, + "humidity": 68.2, + "water_total": 2000.0, + "average_temperature": 34.7333, + "experience_temperature": 31.5067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T14:40:06.355267+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.5, + "humidity": 66.4, + "water_total": 2025.0, + "average_temperature": 34.7333, + "experience_temperature": 30.43, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T14:50:06.439418+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 66.2, + "water_total": 2055.0, + "average_temperature": 34.6667, + "experience_temperature": 31.7567, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T15:10:06.268926+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 68.8, + "water_total": 2110.0, + "average_temperature": 34.6, + "experience_temperature": 32.9267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T15:20:07.719377+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 67.5, + "water_total": 2137.0, + "average_temperature": 34.6333, + "experience_temperature": 31.9833, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T15:30:06.736048+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 68.3, + "water_total": 2165.0, + "average_temperature": 34.1667, + "experience_temperature": 32.3933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T15:40:06.690144+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.3, + "humidity": 68.7, + "water_total": 2196.0, + "average_temperature": 33.6667, + "experience_temperature": 31.2567, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T15:50:07.116250+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 69.1, + "water_total": 2218.0, + "average_temperature": 33.6333, + "experience_temperature": 32.02, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T16:10:06.868234+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 70.3, + "water_total": 2274.0, + "average_temperature": 33.5, + "experience_temperature": 32.1267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T16:20:06.365660+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.2, + "humidity": 71.5, + "water_total": 2295.0, + "average_temperature": 33.6, + "experience_temperature": 32.4667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T16:30:09.035473+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.1, + "humidity": 69.7, + "water_total": 2316.0, + "average_temperature": 33.4, + "experience_temperature": 32.6233, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T16:40:07.331641+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.1, + "humidity": 71.9, + "water_total": 2346.0, + "average_temperature": 34.0333, + "experience_temperature": 33.6967, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T16:50:07.350257+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 71.7, + "water_total": 2371.0, + "average_temperature": 33.4333, + "experience_temperature": 33.7733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T17:10:07.931092+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 71.5, + "water_total": 20.0, + "average_temperature": 33.4, + "experience_temperature": 33.7, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T17:20:08.181727+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 72.3, + "water_total": 51.0, + "average_temperature": 33.1333, + "experience_temperature": 33.5933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T17:30:07.114958+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 73.1, + "water_total": 73.0, + "average_temperature": 33.1333, + "experience_temperature": 33.7533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T17:40:06.879633+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 74.6, + "water_total": 105.0, + "average_temperature": 33.0333, + "experience_temperature": 33.9533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T17:50:09.183252+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 75.2, + "water_total": 126.0, + "average_temperature": 32.7667, + "experience_temperature": 33.8067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:00:08.027684+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 76.1, + "water_total": 153.0, + "average_temperature": 32.7667, + "experience_temperature": 33.9867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:10:06.102068+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 76.6, + "water_total": 174.0, + "average_temperature": 32.5, + "experience_temperature": 33.82, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:20:07.067826+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 77.6, + "water_total": 196.0, + "average_temperature": 32.4333, + "experience_temperature": 33.9533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:30:06.745096+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.5, + "water_total": 219.0, + "average_temperature": 32.3, + "experience_temperature": 34.2, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:40:06.690772+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 239.0, + "average_temperature": 32.2333, + "experience_temperature": 34.1733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T18:50:07.213091+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 263.0, + "average_temperature": 32.1667, + "experience_temperature": 34.1267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:00:11.215176+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 287.0, + "average_temperature": 32.0333, + "experience_temperature": 33.8933, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:10:08.122375+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 299.0, + "average_temperature": 31.7333, + "experience_temperature": 33.7533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:20:06.942097+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 322.0, + "average_temperature": 31.6667, + "experience_temperature": 33.6667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:30:12.280164+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 333.0, + "average_temperature": 31.5333, + "experience_temperature": 33.6333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:40:07.470382+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 339.0, + "average_temperature": 31.4333, + "experience_temperature": 33.5133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T19:50:07.470889+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 346.0, + "average_temperature": 31.3333, + "experience_temperature": 33.6533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:00:07.182172+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 346.0, + "average_temperature": 31.3, + "experience_temperature": 33.76, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:10:06.701858+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 347.0, + "average_temperature": 31.2, + "experience_temperature": 33.5, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:20:07.116011+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 348.0, + "average_temperature": 31.0667, + "experience_temperature": 33.3667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:30:09.219036+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 351.0, + "average_temperature": 32.5, + "experience_temperature": 34.84, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:40:07.360939+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 352.0, + "average_temperature": 31.9333, + "experience_temperature": 34.0133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T20:50:06.887489+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.6, + "water_total": 355.0, + "average_temperature": 31.7333, + "experience_temperature": 33.8533, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:00:07.798133+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 358.0, + "average_temperature": 31.4333, + "experience_temperature": 33.5733, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:10:06.778828+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 360.0, + "average_temperature": 31.2667, + "experience_temperature": 33.4267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:20:07.286283+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 360.0, + "average_temperature": 31.2667, + "experience_temperature": 33.4267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:30:08.240753+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.6, + "water_total": 369.0, + "average_temperature": 32.2667, + "experience_temperature": 34.3867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:40:09.092179+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 376.0, + "average_temperature": 31.7667, + "experience_temperature": 33.8667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T21:50:11.084788+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 387.0, + "average_temperature": 31.4, + "experience_temperature": 33.58, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:00:06.610001+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 396.0, + "average_temperature": 31.2667, + "experience_temperature": 33.5467, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:10:06.932352+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 408.0, + "average_temperature": 31.4667, + "experience_temperature": 34.1867, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:20:06.611299+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 434.0, + "average_temperature": 32.3667, + "experience_temperature": 34.5067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:30:07.188905+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 451.0, + "average_temperature": 31.7667, + "experience_temperature": 33.9267, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:40:06.933397+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 459.0, + "average_temperature": 31.3667, + "experience_temperature": 33.5667, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T22:50:06.917792+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 483.0, + "average_temperature": 31.4, + "experience_temperature": 33.58, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:00:11.163159+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 492.0, + "average_temperature": 31.2667, + "experience_temperature": 34.1067, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:10:07.250866+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 511.0, + "average_temperature": 32.1, + "experience_temperature": 34.04, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:20:08.876365+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 527.0, + "average_temperature": 31.5, + "experience_temperature": 33.6, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:30:08.035657+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 552.0, + "average_temperature": 31.2333, + "experience_temperature": 33.8333, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:40:08.855333+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 560.0, + "average_temperature": 32.1333, + "experience_temperature": 34.2133, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-27T23:50:07.308284+07:00", + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.9, + "water_total": 582.0, + "average_temperature": 31.5, + "experience_temperature": 33.48, + "chill_factor": 7.1667 + }, + { + "timestamp": "2026-05-28T00:00:06.904526+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 596.0, + "average_temperature": 31.3, + "experience_temperature": 33.92, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T00:10:05.825038+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 610.0, + "average_temperature": 31.3667, + "experience_temperature": 33.3067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T00:20:06.005672+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 625.0, + "average_temperature": 30.7333, + "experience_temperature": 33.0533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T00:30:07.408173+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.3, + "water_total": 643.0, + "average_temperature": 31.8667, + "experience_temperature": 33.9267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T00:40:05.890320+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 664.0, + "average_temperature": 31.1, + "experience_temperature": 33.04, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T00:50:06.121259+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 684.0, + "average_temperature": 31.6, + "experience_temperature": 34.02, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:00:06.025736+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 706.0, + "average_temperature": 31.2, + "experience_temperature": 33.14, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:10:08.522681+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 726.0, + "average_temperature": 31.0667, + "experience_temperature": 33.5667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:20:09.770352+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 748.0, + "average_temperature": 31.5667, + "experience_temperature": 33.7667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:30:06.190510+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 762.0, + "average_temperature": 30.7667, + "experience_temperature": 32.7067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:40:08.363013+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.6, + "water_total": 780.0, + "average_temperature": 31.8, + "experience_temperature": 33.72, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T01:50:05.729600+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.6, + "water_total": 780.0, + "average_temperature": 31.8, + "experience_temperature": 33.72, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:00:06.132141+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 821.0, + "average_temperature": 31.7333, + "experience_temperature": 34.0333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:10:05.898271+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 839.0, + "average_temperature": 31.2, + "experience_temperature": 32.94, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:20:07.138873+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 868.0, + "average_temperature": 30.9333, + "experience_temperature": 33.2133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:30:05.121275+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 904.0, + "average_temperature": 31.6, + "experience_temperature": 34.28, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:40:08.979583+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 935.0, + "average_temperature": 31.1333, + "experience_temperature": 33.0933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T02:50:05.458305+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 955.0, + "average_temperature": 31.5667, + "experience_temperature": 34.1867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:00:08.882811+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 983.0, + "average_temperature": 31.2667, + "experience_temperature": 33.2267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:10:05.952781+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 1011.0, + "average_temperature": 30.7333, + "experience_temperature": 32.5933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:20:09.039035+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 1031.0, + "average_temperature": 31.5, + "experience_temperature": 33.9, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:30:05.717861+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.6, + "water_total": 1046.0, + "average_temperature": 30.9, + "experience_temperature": 33.02, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:40:06.482216+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 1074.0, + "average_temperature": 31.5333, + "experience_temperature": 34.1533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T03:50:05.709627+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 1093.0, + "average_temperature": 30.5667, + "experience_temperature": 32.4267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:00:06.846158+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 1107.0, + "average_temperature": 31.6667, + "experience_temperature": 34.0067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:10:07.967440+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.5, + "water_total": 1138.0, + "average_temperature": 30.8333, + "experience_temperature": 32.5333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:20:06.184193+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 1159.0, + "average_temperature": 31.7667, + "experience_temperature": 34.1867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:30:08.342192+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.8, + "water_total": 1180.0, + "average_temperature": 30.9, + "experience_temperature": 32.66, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:40:07.835050+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 1210.0, + "average_temperature": 31.7, + "experience_temperature": 33.92, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T04:50:06.288625+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 1235.0, + "average_temperature": 30.9333, + "experience_temperature": 32.6133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:00:08.686593+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 1259.0, + "average_temperature": 31.7, + "experience_temperature": 33.94, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:10:07.230402+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.1, + "water_total": 1285.0, + "average_temperature": 30.9, + "experience_temperature": 32.52, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:20:05.566230+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.8, + "water_total": 1305.0, + "average_temperature": 31.6333, + "experience_temperature": 33.9933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:30:08.172996+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 1329.0, + "average_temperature": 30.7333, + "experience_temperature": 32.4733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:40:05.955703+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 1365.0, + "average_temperature": 31.5, + "experience_temperature": 33.84, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T05:50:05.671748+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 1392.0, + "average_temperature": 30.8333, + "experience_temperature": 33.3733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:00:08.355580+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.3, + "water_total": 1416.0, + "average_temperature": 31.6333, + "experience_temperature": 33.2933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:10:06.639091+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 1433.0, + "average_temperature": 30.5333, + "experience_temperature": 32.2133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:20:07.697738+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 1463.0, + "average_temperature": 31.3667, + "experience_temperature": 33.6667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:30:05.530483+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 1489.0, + "average_temperature": 30.6333, + "experience_temperature": 32.4733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:40:05.799214+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.4, + "water_total": 1506.0, + "average_temperature": 31.4, + "experience_temperature": 33.28, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T06:50:08.316986+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.6, + "water_total": 1540.0, + "average_temperature": 30.9333, + "experience_temperature": 32.8533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:00:06.651735+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 1567.0, + "average_temperature": 30.8, + "experience_temperature": 33.02, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:10:06.444859+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 77.5, + "water_total": 1600.0, + "average_temperature": 31.7667, + "experience_temperature": 33.2667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:20:08.667793+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 1627.0, + "average_temperature": 31.4333, + "experience_temperature": 33.5933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:30:05.908214+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 1654.0, + "average_temperature": 31.1, + "experience_temperature": 32.94, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:40:06.851428+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 1685.0, + "average_temperature": 31.1667, + "experience_temperature": 33.4067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T07:50:06.488574+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 1715.0, + "average_temperature": 31.3333, + "experience_temperature": 33.3333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:00:08.155538+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 1742.0, + "average_temperature": 31.6, + "experience_temperature": 33.68, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:10:10.200901+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 1766.0, + "average_temperature": 32.1, + "experience_temperature": 33.7, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:20:06.061160+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 1794.0, + "average_temperature": 32.2667, + "experience_temperature": 34.0067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:30:08.662188+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 76.4, + "water_total": 1824.0, + "average_temperature": 32.1667, + "experience_temperature": 33.4467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:40:06.227282+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 74.9, + "water_total": 1850.0, + "average_temperature": 32.3333, + "experience_temperature": 33.3133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T08:50:05.875290+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 76.0, + "water_total": 1887.0, + "average_temperature": 32.3667, + "experience_temperature": 33.5667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:00:06.123233+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 74.6, + "water_total": 1911.0, + "average_temperature": 32.4333, + "experience_temperature": 33.3533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:10:07.057326+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 73.3, + "water_total": 1941.0, + "average_temperature": 32.6333, + "experience_temperature": 31.8933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:20:08.405634+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 72.0, + "water_total": 1966.0, + "average_temperature": 32.8, + "experience_temperature": 33.2, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:30:07.084852+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.1, + "humidity": 70.5, + "water_total": 1996.0, + "average_temperature": 32.7667, + "experience_temperature": 32.1667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:40:08.688071+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 69.1, + "water_total": 2024.0, + "average_temperature": 32.7667, + "experience_temperature": 31.1867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T09:50:06.375487+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 67.7, + "water_total": 2052.0, + "average_temperature": 32.9, + "experience_temperature": 31.04, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:00:06.196396+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 69.4, + "water_total": 2086.0, + "average_temperature": 33.3, + "experience_temperature": 31.78, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:10:09.534679+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 65.9, + "water_total": 2119.0, + "average_temperature": 33.5667, + "experience_temperature": 31.3467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:20:06.729747+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 66.1, + "water_total": 2144.0, + "average_temperature": 33.8, + "experience_temperature": 31.62, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:30:07.359406+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.3, + "humidity": 64.1, + "water_total": 2171.0, + "average_temperature": 34.0, + "experience_temperature": 30.72, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:40:08.586666+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.3, + "humidity": 64.5, + "water_total": 2203.0, + "average_temperature": 34.0, + "experience_temperature": 30.8, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T10:50:06.436306+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 62.3, + "water_total": 2233.0, + "average_temperature": 34.0, + "experience_temperature": 31.06, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:00:07.298591+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 62.3, + "water_total": 2233.0, + "average_temperature": 34.0, + "experience_temperature": 31.06, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:10:06.369905+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 61.5, + "water_total": 2296.0, + "average_temperature": 34.0667, + "experience_temperature": 28.1667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:20:06.806455+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 61.5, + "water_total": 2296.0, + "average_temperature": 34.0667, + "experience_temperature": 28.1667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:30:08.177804+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.8, + "humidity": 58.0, + "water_total": 2358.0, + "average_temperature": 34.4, + "experience_temperature": 26.4, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:40:06.826561+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.7, + "humidity": 58.1, + "water_total": 2393.0, + "average_temperature": 34.5, + "experience_temperature": 27.22, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T11:50:08.175482+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.7, + "humidity": 57.5, + "water_total": 2421.0, + "average_temperature": 34.3667, + "experience_temperature": 26.9667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:00:06.780927+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.8, + "humidity": 59.1, + "water_total": 2449.0, + "average_temperature": 34.8, + "experience_temperature": 27.02, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:10:06.794047+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.8, + "humidity": 58.2, + "water_total": 2480.0, + "average_temperature": 34.7, + "experience_temperature": 26.74, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:20:08.909130+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.7, + "humidity": 58.1, + "water_total": 2510.0, + "average_temperature": 34.7, + "experience_temperature": 27.42, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:30:06.889220+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.7, + "humidity": 58.1, + "water_total": 2510.0, + "average_temperature": 34.7, + "experience_temperature": 27.42, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:40:06.335873+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.8, + "humidity": 55.9, + "water_total": 2561.0, + "average_temperature": 34.6333, + "experience_temperature": 26.2133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T12:50:07.216643+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.0, + "humidity": 57.1, + "water_total": 2595.0, + "average_temperature": 34.7333, + "experience_temperature": 25.1533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:00:06.390099+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.1, + "humidity": 57.8, + "water_total": 2622.0, + "average_temperature": 34.8333, + "experience_temperature": 24.6933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:10:06.557607+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.7, + "humidity": 57.1, + "water_total": 2645.0, + "average_temperature": 34.7667, + "experience_temperature": 27.2867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:20:07.131612+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 54.5, + "water_total": 2675.0, + "average_temperature": 34.5667, + "experience_temperature": 27.2667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:30:07.818617+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.0, + "humidity": 55.7, + "water_total": 2704.0, + "average_temperature": 34.8, + "experience_temperature": 24.94, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:40:07.664907+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.0, + "humidity": 55.2, + "water_total": 2737.0, + "average_temperature": 34.8333, + "experience_temperature": 24.8733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T13:50:06.479666+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.0, + "humidity": 55.2, + "water_total": 2737.0, + "average_temperature": 34.8333, + "experience_temperature": 24.8733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T14:10:09.788746+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 1.1, + "humidity": 55.6, + "water_total": 2817.0, + "average_temperature": 34.9333, + "experience_temperature": 24.3533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T14:20:08.794000+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.9, + "humidity": 56.4, + "water_total": 2843.0, + "average_temperature": 34.7667, + "experience_temperature": 25.7467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T14:30:06.989714+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 57.8, + "water_total": 2871.0, + "average_temperature": 34.5, + "experience_temperature": 27.86, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T14:40:07.411972+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.5, + "humidity": 61.1, + "water_total": 2904.0, + "average_temperature": 34.1, + "experience_temperature": 28.82, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T14:50:08.374139+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 58.6, + "water_total": 2932.0, + "average_temperature": 34.0, + "experience_temperature": 27.52, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T15:10:06.020247+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 59.7, + "water_total": 2990.0, + "average_temperature": 34.5333, + "experience_temperature": 28.2733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T15:20:06.336886+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 59.5, + "water_total": 3019.0, + "average_temperature": 34.5, + "experience_temperature": 28.2, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T15:30:06.854307+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.6, + "humidity": 63.3, + "water_total": 3046.0, + "average_temperature": 34.3667, + "experience_temperature": 28.8267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T15:40:06.985888+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.3, + "humidity": 59.9, + "water_total": 3070.0, + "average_temperature": 33.6667, + "experience_temperature": 29.5467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T15:50:07.773597+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 61.7, + "water_total": 3097.0, + "average_temperature": 33.4333, + "experience_temperature": 30.3733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T16:10:06.228688+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 66.5, + "water_total": 3150.0, + "average_temperature": 32.6333, + "experience_temperature": 30.5333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T16:20:06.617743+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 67.6, + "water_total": 3180.0, + "average_temperature": 32.3333, + "experience_temperature": 30.4533, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T16:30:06.329065+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.2, + "humidity": 68.4, + "water_total": 3205.0, + "average_temperature": 32.7667, + "experience_temperature": 31.0467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T16:40:08.907938+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.1, + "humidity": 68.7, + "water_total": 3234.0, + "average_temperature": 32.7667, + "experience_temperature": 31.8067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T16:50:05.953279+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.1, + "humidity": 71.0, + "water_total": 3262.0, + "average_temperature": 32.5667, + "experience_temperature": 32.0667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T17:10:07.134915+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 71.0, + "water_total": 32.0, + "average_temperature": 32.2333, + "experience_temperature": 32.4333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T17:20:07.220425+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 71.9, + "water_total": 62.0, + "average_temperature": 32.0333, + "experience_temperature": 32.4133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T17:30:06.218337+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 71.5, + "water_total": 87.0, + "average_temperature": 31.8, + "experience_temperature": 32.1, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T17:40:06.657766+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 71.5, + "water_total": 87.0, + "average_temperature": 31.8, + "experience_temperature": 32.1, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T17:50:10.492574+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 72.8, + "water_total": 139.0, + "average_temperature": 31.6667, + "experience_temperature": 32.2267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:00:06.152505+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 72.8, + "water_total": 139.0, + "average_temperature": 31.6667, + "experience_temperature": 32.2267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:10:06.592056+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 72.8, + "water_total": 205.0, + "average_temperature": 31.4, + "experience_temperature": 31.96, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:20:06.333077+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 75.8, + "water_total": 234.0, + "average_temperature": 31.5667, + "experience_temperature": 32.7267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:30:07.236995+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 74.8, + "water_total": 263.0, + "average_temperature": 31.4333, + "experience_temperature": 32.3933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:40:06.183109+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 75.1, + "water_total": 292.0, + "average_temperature": 31.3, + "experience_temperature": 32.32, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T18:50:06.890959+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 77.5, + "water_total": 318.0, + "average_temperature": 31.3667, + "experience_temperature": 32.8667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:00:07.265687+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 77.8, + "water_total": 350.0, + "average_temperature": 31.4, + "experience_temperature": 32.96, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:10:06.916635+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 383.0, + "average_temperature": 31.2667, + "experience_temperature": 32.7467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:20:06.832569+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 76.8, + "water_total": 411.0, + "average_temperature": 31.1333, + "experience_temperature": 32.4933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:30:06.909875+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 440.0, + "average_temperature": 30.9667, + "experience_temperature": 32.4467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:40:06.811920+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 460.0, + "average_temperature": 31.1333, + "experience_temperature": 32.8133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T19:50:06.118142+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 487.0, + "average_temperature": 31.0, + "experience_temperature": 32.78, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:00:06.713743+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 519.0, + "average_temperature": 30.9667, + "experience_temperature": 32.9867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:10:07.314466+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 553.0, + "average_temperature": 30.6, + "experience_temperature": 32.44, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:20:07.002632+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.8, + "water_total": 581.0, + "average_temperature": 30.6667, + "experience_temperature": 32.4267, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:30:06.523766+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 604.0, + "average_temperature": 30.4333, + "experience_temperature": 32.2133, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:40:06.297660+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.6, + "water_total": 626.0, + "average_temperature": 30.4, + "experience_temperature": 32.32, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T20:50:09.118116+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.4, + "water_total": 653.0, + "average_temperature": 30.1667, + "experience_temperature": 32.0467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:00:06.883594+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 679.0, + "average_temperature": 31.2667, + "experience_temperature": 33.8467, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:10:06.845521+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.4, + "water_total": 705.0, + "average_temperature": 31.3, + "experience_temperature": 33.18, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:20:06.194602+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 731.0, + "average_temperature": 30.5333, + "experience_temperature": 32.2733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:30:07.781453+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 752.0, + "average_temperature": 30.2, + "experience_temperature": 32.22, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:40:06.598768+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 775.0, + "average_temperature": 30.5667, + "experience_temperature": 32.7667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T21:50:06.452334+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 809.0, + "average_temperature": 31.4, + "experience_temperature": 33.26, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:00:06.852950+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 827.0, + "average_temperature": 30.5333, + "experience_temperature": 32.5333, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:10:06.685008+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 852.0, + "average_temperature": 30.2333, + "experience_temperature": 32.3733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:20:07.078730+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 878.0, + "average_temperature": 31.4, + "experience_temperature": 33.36, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:30:06.721201+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 900.0, + "average_temperature": 30.9667, + "experience_temperature": 32.9067, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:40:06.662208+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 928.0, + "average_temperature": 30.5, + "experience_temperature": 32.68, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T22:50:07.386317+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.6, + "water_total": 955.0, + "average_temperature": 30.5, + "experience_temperature": 32.62, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:00:06.920077+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 973.0, + "average_temperature": 29.9667, + "experience_temperature": 31.9867, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:10:07.445427+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.0, + "water_total": 990.0, + "average_temperature": 31.1667, + "experience_temperature": 32.9667, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:20:06.755023+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 1012.0, + "average_temperature": 30.3, + "experience_temperature": 32.3, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:30:06.721279+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 1030.0, + "average_temperature": 30.1333, + "experience_temperature": 32.3733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:40:06.624365+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 1047.0, + "average_temperature": 31.0333, + "experience_temperature": 32.8733, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-28T23:50:06.270665+07:00", + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 1065.0, + "average_temperature": 30.4333, + "experience_temperature": 32.3933, + "chill_factor": 7.0 + }, + { + "timestamp": "2026-05-29T00:00:08.602695+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 1083.0, + "average_temperature": 30.6, + "experience_temperature": 33.02, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T00:10:07.381250+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 1100.0, + "average_temperature": 30.4333, + "experience_temperature": 32.2733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T00:20:08.531104+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 1117.0, + "average_temperature": 29.8, + "experience_temperature": 31.8, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T00:30:06.048478+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 1135.0, + "average_temperature": 30.3667, + "experience_temperature": 32.1067, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T00:40:06.237967+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 1154.0, + "average_temperature": 29.8, + "experience_temperature": 31.82, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T00:50:06.565624+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.8, + "water_total": 1166.0, + "average_temperature": 30.3667, + "experience_temperature": 32.1267, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:00:06.554693+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.5, + "water_total": 1185.0, + "average_temperature": 29.8, + "experience_temperature": 31.7, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:10:06.033389+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 1207.0, + "average_temperature": 30.3, + "experience_temperature": 32.08, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:20:06.014420+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 1224.0, + "average_temperature": 30.2667, + "experience_temperature": 32.2667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:30:06.482185+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 1242.0, + "average_temperature": 30.0333, + "experience_temperature": 31.7133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:40:06.711073+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.5, + "water_total": 1256.0, + "average_temperature": 30.6, + "experience_temperature": 32.5, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T01:50:06.222495+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.7, + "water_total": 1275.0, + "average_temperature": 29.7667, + "experience_temperature": 31.5067, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:00:06.098586+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.6, + "water_total": 1293.0, + "average_temperature": 30.5333, + "experience_temperature": 32.0533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:10:07.153079+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 1321.0, + "average_temperature": 29.8, + "experience_temperature": 31.64, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:20:07.531403+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.6, + "water_total": 1358.0, + "average_temperature": 30.7, + "experience_temperature": 32.42, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:30:07.029131+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 1386.0, + "average_temperature": 29.9333, + "experience_temperature": 32.1133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:40:07.032124+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.7, + "water_total": 1414.0, + "average_temperature": 30.4667, + "experience_temperature": 32.0067, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T02:50:06.654298+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 1453.0, + "average_temperature": 29.8667, + "experience_temperature": 31.8867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:00:06.239518+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.4, + "water_total": 1483.0, + "average_temperature": 30.4333, + "experience_temperature": 32.3133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:10:06.326752+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.7, + "water_total": 1511.0, + "average_temperature": 29.7667, + "experience_temperature": 31.7067, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:20:06.821129+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 1529.0, + "average_temperature": 31.1333, + "experience_temperature": 32.7333, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:30:05.746899+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.9, + "water_total": 1574.0, + "average_temperature": 29.9, + "experience_temperature": 31.88, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:40:06.676674+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 1599.0, + "average_temperature": 30.7667, + "experience_temperature": 33.1867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T03:50:06.991605+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.5, + "water_total": 1627.0, + "average_temperature": 30.3, + "experience_temperature": 32.0, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:00:06.409185+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.1, + "water_total": 1650.0, + "average_temperature": 29.8333, + "experience_temperature": 31.6533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:10:06.369531+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 1685.0, + "average_temperature": 31.0333, + "experience_temperature": 33.1133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:20:06.232730+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.7, + "water_total": 1713.0, + "average_temperature": 29.9, + "experience_temperature": 31.44, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:30:06.092055+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 1731.0, + "average_temperature": 30.8, + "experience_temperature": 32.88, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:40:06.890582+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 1754.0, + "average_temperature": 30.0, + "experience_temperature": 31.48, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T04:50:06.160558+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 1782.0, + "average_temperature": 30.9, + "experience_temperature": 33.0, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:00:06.952569+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 77.3, + "water_total": 1815.0, + "average_temperature": 30.3333, + "experience_temperature": 31.1076, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:10:07.640799+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 1841.0, + "average_temperature": 30.2333, + "experience_temperature": 32.7733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:20:07.127017+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 76.7, + "water_total": 1876.0, + "average_temperature": 30.5, + "experience_temperature": 31.84, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:30:08.407788+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 1899.0, + "average_temperature": 30.2, + "experience_temperature": 32.38, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:40:06.897728+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 76.2, + "water_total": 1928.0, + "average_temperature": 30.4333, + "experience_temperature": 31.6733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T05:50:06.888959+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.1, + "water_total": 1953.0, + "average_temperature": 29.6, + "experience_temperature": 31.42, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:00:05.936017+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.6, + "water_total": 1983.0, + "average_temperature": 31.0, + "experience_temperature": 32.52, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:10:08.877296+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 2018.0, + "average_temperature": 29.5667, + "experience_temperature": 31.3467, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:20:06.375533+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 2043.0, + "average_temperature": 30.7, + "experience_temperature": 32.3, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:30:07.345405+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.5, + "water_total": 2074.0, + "average_temperature": 30.0667, + "experience_temperature": 31.9667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:40:07.048330+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.2, + "water_total": 2104.0, + "average_temperature": 29.8, + "experience_temperature": 31.44, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T06:50:07.588421+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.2, + "water_total": 2104.0, + "average_temperature": 29.8, + "experience_temperature": 31.44, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:00:06.798228+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.1, + "water_total": 2171.0, + "average_temperature": 30.2667, + "experience_temperature": 31.8867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:10:06.863640+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 2200.0, + "average_temperature": 29.5, + "experience_temperature": 31.58, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:20:07.044488+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 2236.0, + "average_temperature": 31.3667, + "experience_temperature": 33.1467, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:30:06.302014+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.2, + "water_total": 2270.0, + "average_temperature": 30.8333, + "experience_temperature": 32.6733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:40:06.836089+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 2300.0, + "average_temperature": 30.9667, + "experience_temperature": 32.9667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T07:50:06.513805+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 2316.0, + "average_temperature": 30.8667, + "experience_temperature": 32.4667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:00:11.534324+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 2341.0, + "average_temperature": 30.9333, + "experience_temperature": 32.4133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:10:07.340265+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 2341.0, + "average_temperature": 30.9333, + "experience_temperature": 32.4133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:20:06.281777+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 2403.0, + "average_temperature": 30.9333, + "experience_temperature": 32.7133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:30:06.647332+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 2436.0, + "average_temperature": 31.0667, + "experience_temperature": 32.6667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:40:07.640228+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 77.8, + "water_total": 2472.0, + "average_temperature": 31.5667, + "experience_temperature": 32.441, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T08:50:07.288846+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 75.4, + "water_total": 2510.0, + "average_temperature": 31.5667, + "experience_temperature": 30.5895, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:00:06.903502+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 72.5, + "water_total": 2550.0, + "average_temperature": 31.5333, + "experience_temperature": 31.3476, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:10:09.131006+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 72.1, + "water_total": 2583.0, + "average_temperature": 31.7, + "experience_temperature": 30.7486, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:20:06.682301+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 72.9, + "water_total": 2611.0, + "average_temperature": 31.8667, + "experience_temperature": 31.0752, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:30:06.848890+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 70.1, + "water_total": 2640.0, + "average_temperature": 32.2333, + "experience_temperature": 30.8819, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:40:06.288020+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 70.0, + "water_total": 2676.0, + "average_temperature": 32.8333, + "experience_temperature": 30.7762, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T09:50:07.771965+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 70.5, + "water_total": 2704.0, + "average_temperature": 32.4333, + "experience_temperature": 30.4762, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:00:06.998645+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 70.4, + "water_total": 2732.0, + "average_temperature": 32.5, + "experience_temperature": 31.2086, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:10:07.197057+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 69.2, + "water_total": 2744.0, + "average_temperature": 32.5333, + "experience_temperature": 30.3162, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:20:06.721356+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.8, + "humidity": 68.2, + "water_total": 2761.0, + "average_temperature": 32.7667, + "experience_temperature": 26.921, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:30:07.449142+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.8, + "humidity": 67.7, + "water_total": 2787.0, + "average_temperature": 32.9333, + "experience_temperature": 26.9876, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:40:06.937698+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.7, + "humidity": 66.7, + "water_total": 2806.0, + "average_temperature": 33.2, + "experience_temperature": 27.74, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T10:50:06.507299+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.6, + "humidity": 67.2, + "water_total": 2806.0, + "average_temperature": 33.3, + "experience_temperature": 28.6257, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:00:06.935159+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.7, + "humidity": 65.8, + "water_total": 2815.0, + "average_temperature": 33.4333, + "experience_temperature": 27.7933, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:10:07.489526+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.7, + "humidity": 67.6, + "water_total": 2817.0, + "average_temperature": 33.4667, + "experience_temperature": 28.1867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:20:06.481105+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.7, + "humidity": 65.7, + "water_total": 2822.0, + "average_temperature": 33.5333, + "experience_temperature": 27.8733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:30:06.996339+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 67.1, + "water_total": 2831.0, + "average_temperature": 33.6333, + "experience_temperature": 26.1962, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:40:06.603784+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.1, + "humidity": 65.2, + "water_total": 2850.0, + "average_temperature": 33.5, + "experience_temperature": 24.9971, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T11:50:06.522583+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.1, + "humidity": 66.1, + "water_total": 2872.0, + "average_temperature": 33.5333, + "experience_temperature": 25.2105, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:00:07.694223+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 65.5, + "water_total": 2900.0, + "average_temperature": 33.6667, + "experience_temperature": 25.9095, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:10:07.379530+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.2, + "humidity": 67.3, + "water_total": 2930.0, + "average_temperature": 34.0333, + "experience_temperature": 25.2648, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:20:06.356489+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.8, + "humidity": 66.9, + "water_total": 2954.0, + "average_temperature": 34.0, + "experience_temperature": 27.8943, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:30:06.323072+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.9, + "humidity": 65.5, + "water_total": 2985.0, + "average_temperature": 33.8, + "experience_temperature": 26.7286, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:40:07.364968+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.9, + "humidity": 66.4, + "water_total": 3003.0, + "average_temperature": 33.8667, + "experience_temperature": 26.9752, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T12:50:06.006852+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.1, + "humidity": 64.1, + "water_total": 3025.0, + "average_temperature": 33.7667, + "experience_temperature": 25.0438, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:00:06.628202+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.2, + "humidity": 63.3, + "water_total": 3043.0, + "average_temperature": 33.9333, + "experience_temperature": 24.3648, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:10:05.984317+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.9, + "humidity": 63.5, + "water_total": 3063.0, + "average_temperature": 34.1, + "experience_temperature": 26.6286, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:20:06.177186+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.1, + "humidity": 64.3, + "water_total": 3081.0, + "average_temperature": 34.2, + "experience_temperature": 25.5171, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:30:08.156595+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.2, + "humidity": 65.3, + "water_total": 3108.0, + "average_temperature": 34.2, + "experience_temperature": 25.0314, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:40:06.616834+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.8, + "humidity": 63.8, + "water_total": 3128.0, + "average_temperature": 34.2, + "experience_temperature": 27.4743, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T13:50:05.894534+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.9, + "humidity": 64.0, + "water_total": 3152.0, + "average_temperature": 34.1, + "experience_temperature": 26.7286, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T14:10:06.255068+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 65.6, + "water_total": 3302.0, + "average_temperature": 34.2333, + "experience_temperature": 26.4962, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T14:20:05.671174+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 64.2, + "water_total": 3385.0, + "average_temperature": 34.1667, + "experience_temperature": 26.1495, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T14:30:06.466415+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 64.2, + "water_total": 3385.0, + "average_temperature": 34.1667, + "experience_temperature": 26.1495, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T14:40:08.002621+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.2, + "humidity": 66.0, + "water_total": 3552.0, + "average_temperature": 33.7, + "experience_temperature": 24.6714, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T14:50:09.723974+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.2, + "humidity": 63.5, + "water_total": 3561.0, + "average_temperature": 33.6333, + "experience_temperature": 24.1048, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T15:10:06.616374+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 66.0, + "water_total": 3580.0, + "average_temperature": 33.7, + "experience_temperature": 26.0429, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T15:20:05.813999+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.0, + "humidity": 65.9, + "water_total": 3632.0, + "average_temperature": 33.5333, + "experience_temperature": 25.8562, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T15:30:06.040572+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 1.1, + "humidity": 66.6, + "water_total": 3644.0, + "average_temperature": 33.4667, + "experience_temperature": 25.2438, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T15:40:06.857370+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.7, + "humidity": 68.4, + "water_total": 3680.0, + "average_temperature": 33.0667, + "experience_temperature": 27.9467, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T15:50:06.176683+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.6, + "humidity": 71.9, + "water_total": 3720.0, + "average_temperature": 32.5333, + "experience_temperature": 28.799, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T16:10:06.022220+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 73.1, + "water_total": 3851.0, + "average_temperature": 32.4, + "experience_temperature": 30.9629, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T16:20:06.068574+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 71.9, + "water_total": 3873.0, + "average_temperature": 32.3333, + "experience_temperature": 31.3419, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T16:30:08.331369+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 72.8, + "water_total": 3890.0, + "average_temperature": 32.4333, + "experience_temperature": 30.9362, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T16:40:06.816170+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 71.6, + "water_total": 3958.0, + "average_temperature": 31.9667, + "experience_temperature": 30.2295, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T16:50:06.536424+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.3, + "humidity": 72.3, + "water_total": 4010.0, + "average_temperature": 31.7, + "experience_temperature": 30.1029, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T17:10:06.018913+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 72.4, + "water_total": 40.0, + "average_temperature": 31.5667, + "experience_temperature": 30.6752, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T17:20:05.944914+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 72.0, + "water_total": 81.0, + "average_temperature": 32.0667, + "experience_temperature": 31.0952, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T17:30:06.390117+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 73.4, + "water_total": 124.0, + "average_temperature": 31.8333, + "experience_temperature": 31.1419, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T17:40:06.449263+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.2, + "humidity": 72.4, + "water_total": 181.0, + "average_temperature": 31.5667, + "experience_temperature": 30.6752, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T17:50:07.479880+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 75.3, + "water_total": 228.0, + "average_temperature": 31.4, + "experience_temperature": 32.46, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:00:06.103724+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 77.6, + "water_total": 268.0, + "average_temperature": 31.4667, + "experience_temperature": 32.301, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:10:05.577636+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.4, + "water_total": 312.0, + "average_temperature": 31.4667, + "experience_temperature": 32.9467, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:20:06.625208+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 76.8, + "water_total": 356.0, + "average_temperature": 31.5, + "experience_temperature": 32.86, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:30:06.474928+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.0, + "water_total": 391.0, + "average_temperature": 31.3333, + "experience_temperature": 32.7333, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:40:06.125580+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.0, + "water_total": 434.0, + "average_temperature": 31.4, + "experience_temperature": 33.0, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T18:50:07.308100+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.7, + "water_total": 472.0, + "average_temperature": 31.2333, + "experience_temperature": 32.7733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:00:06.262597+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 77.9, + "water_total": 510.0, + "average_temperature": 31.2, + "experience_temperature": 32.78, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:10:06.269408+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 76.7, + "water_total": 549.0, + "average_temperature": 31.1333, + "experience_temperature": 32.4733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:20:05.933036+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 592.0, + "average_temperature": 31.1333, + "experience_temperature": 32.8133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:30:06.592504+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 78.1, + "water_total": 612.0, + "average_temperature": 30.9667, + "experience_temperature": 31.901, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:40:07.362245+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 78.1, + "water_total": 639.0, + "average_temperature": 30.7667, + "experience_temperature": 32.3867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T19:50:06.479334+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.1, + "water_total": 673.0, + "average_temperature": 30.7, + "experience_temperature": 32.72, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:00:06.336647+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 79.4, + "water_total": 689.0, + "average_temperature": 30.3333, + "experience_temperature": 32.2133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:10:06.265516+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.1, + "humidity": 79.2, + "water_total": 694.0, + "average_temperature": 30.3333, + "experience_temperature": 31.4876, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:20:06.346978+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 694.0, + "average_temperature": 29.8333, + "experience_temperature": 32.0333, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:30:05.724302+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 698.0, + "average_temperature": 30.0, + "experience_temperature": 32.16, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:40:05.877091+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 701.0, + "average_temperature": 30.4333, + "experience_temperature": 32.6733, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T20:50:06.645407+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 708.0, + "average_temperature": 30.5, + "experience_temperature": 32.74, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:00:05.631451+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 713.0, + "average_temperature": 30.2, + "experience_temperature": 32.38, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:10:06.429161+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 721.0, + "average_temperature": 30.2667, + "experience_temperature": 32.7067, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:20:07.063464+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 730.0, + "average_temperature": 30.2, + "experience_temperature": 32.44, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:30:06.579565+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 744.0, + "average_temperature": 30.5, + "experience_temperature": 32.92, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:40:05.887773+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 771.0, + "average_temperature": 30.3667, + "experience_temperature": 32.8667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T21:50:06.985467+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 783.0, + "average_temperature": 30.1667, + "experience_temperature": 32.5667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:00:06.810381+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 800.0, + "average_temperature": 29.9, + "experience_temperature": 32.24, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:10:05.947720+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 805.0, + "average_temperature": 30.0333, + "experience_temperature": 32.4533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:20:05.606049+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 815.0, + "average_temperature": 29.9333, + "experience_temperature": 32.3533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:30:06.175162+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 824.0, + "average_temperature": 30.1333, + "experience_temperature": 32.6133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:40:08.154688+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 834.0, + "average_temperature": 29.9333, + "experience_temperature": 32.4533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T22:50:06.060058+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 852.0, + "average_temperature": 30.0333, + "experience_temperature": 32.7533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:00:06.091938+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 858.0, + "average_temperature": 29.6667, + "experience_temperature": 31.9867, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:10:07.408894+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 861.0, + "average_temperature": 29.6333, + "experience_temperature": 32.2133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:20:05.890481+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 869.0, + "average_temperature": 29.4667, + "experience_temperature": 31.9667, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:30:07.112737+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 879.0, + "average_temperature": 29.5333, + "experience_temperature": 32.2133, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:40:06.097584+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 888.0, + "average_temperature": 30.5, + "experience_temperature": 32.92, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-29T23:50:08.300037+07:00", + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 890.0, + "average_temperature": 30.1333, + "experience_temperature": 32.7533, + "chill_factor": 6.8571 + }, + { + "timestamp": "2026-05-30T00:00:05.792162+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 897.0, + "average_temperature": 29.7333, + "experience_temperature": 32.1133, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T00:10:07.584622+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 910.0, + "average_temperature": 29.4333, + "experience_temperature": 31.7333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T00:20:07.493544+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 910.0, + "average_temperature": 30.5, + "experience_temperature": 32.78, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T00:30:06.677487+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 913.0, + "average_temperature": 29.7333, + "experience_temperature": 32.1333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T00:40:06.480644+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 919.0, + "average_temperature": 29.5667, + "experience_temperature": 32.1867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T00:50:06.867537+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 923.0, + "average_temperature": 30.5333, + "experience_temperature": 32.8533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:00:06.081424+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 932.0, + "average_temperature": 29.9333, + "experience_temperature": 32.4533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:10:06.239127+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 935.0, + "average_temperature": 29.4, + "experience_temperature": 31.98, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:20:05.782981+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 941.0, + "average_temperature": 30.4333, + "experience_temperature": 32.9533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:30:05.871353+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 947.0, + "average_temperature": 29.6667, + "experience_temperature": 32.2467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:40:06.072752+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 956.0, + "average_temperature": 29.4, + "experience_temperature": 32.0, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T01:50:06.078573+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 970.0, + "average_temperature": 30.2333, + "experience_temperature": 32.4733, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:00:07.104399+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 983.0, + "average_temperature": 29.5667, + "experience_temperature": 32.0867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:10:05.812359+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 1011.0, + "average_temperature": 30.7, + "experience_temperature": 33.04, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:20:06.001001+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 1046.0, + "average_temperature": 30.3, + "experience_temperature": 32.46, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:30:06.468395+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 1083.0, + "average_temperature": 29.6667, + "experience_temperature": 32.1267, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:40:05.679377+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1109.0, + "average_temperature": 29.5, + "experience_temperature": 32.38, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T02:50:06.334710+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.8, + "water_total": 1136.0, + "average_temperature": 30.2667, + "experience_temperature": 32.6267, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:00:07.210851+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 1167.0, + "average_temperature": 29.9, + "experience_temperature": 32.22, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:10:05.909699+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 1194.0, + "average_temperature": 29.7333, + "experience_temperature": 32.4933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:20:06.248560+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.8, + "water_total": 1210.0, + "average_temperature": 30.0, + "experience_temperature": 32.36, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:30:06.307231+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 1235.0, + "average_temperature": 29.5, + "experience_temperature": 31.9, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:40:05.978564+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 1260.0, + "average_temperature": 29.5, + "experience_temperature": 31.94, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T03:50:06.530155+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 1280.0, + "average_temperature": 30.3667, + "experience_temperature": 32.7667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:00:05.637502+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 1312.0, + "average_temperature": 29.7333, + "experience_temperature": 32.2333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:10:06.260642+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 1333.0, + "average_temperature": 30.1, + "experience_temperature": 33.0, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:20:05.874791+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 1358.0, + "average_temperature": 30.2, + "experience_temperature": 32.6, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:30:05.885354+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 1380.0, + "average_temperature": 29.3667, + "experience_temperature": 32.0867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:40:06.200083+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 1401.0, + "average_temperature": 30.1333, + "experience_temperature": 32.4333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T04:50:06.802531+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 1421.0, + "average_temperature": 29.8, + "experience_temperature": 32.54, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:00:05.809661+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 1451.0, + "average_temperature": 29.7, + "experience_temperature": 32.42, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:10:06.057078+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 1473.0, + "average_temperature": 30.2667, + "experience_temperature": 33.0667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:20:06.077520+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 1504.0, + "average_temperature": 29.6333, + "experience_temperature": 32.3933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:30:06.934754+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 1528.0, + "average_temperature": 29.7, + "experience_temperature": 32.56, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:40:06.358213+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 1553.0, + "average_temperature": 29.7, + "experience_temperature": 32.28, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T05:50:07.229366+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 1575.0, + "average_temperature": 29.6333, + "experience_temperature": 32.4333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:00:06.461499+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 1593.0, + "average_temperature": 30.3, + "experience_temperature": 32.86, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:10:07.598330+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 1615.0, + "average_temperature": 29.7, + "experience_temperature": 32.44, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:20:06.285686+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 1629.0, + "average_temperature": 29.5333, + "experience_temperature": 32.1533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:30:06.274247+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1651.0, + "average_temperature": 29.6, + "experience_temperature": 32.48, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:40:06.260009+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 1675.0, + "average_temperature": 29.4667, + "experience_temperature": 32.2267, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T06:50:08.147020+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 85.4, + "water_total": 1697.0, + "average_temperature": 29.7, + "experience_temperature": 32.78, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:00:07.202955+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 1710.0, + "average_temperature": 29.2667, + "experience_temperature": 31.9267, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:10:06.736006+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 1725.0, + "average_temperature": 30.4667, + "experience_temperature": 33.0667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:20:06.518260+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 1747.0, + "average_temperature": 30.3667, + "experience_temperature": 32.9467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:30:06.509776+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 1767.0, + "average_temperature": 30.6, + "experience_temperature": 33.36, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:40:07.004092+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 1784.0, + "average_temperature": 30.3333, + "experience_temperature": 32.7533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T07:50:07.235555+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 1796.0, + "average_temperature": 30.6667, + "experience_temperature": 33.4067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:00:06.011033+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 90.5, + "water_total": 1813.0, + "average_temperature": 30.6, + "experience_temperature": 34.7, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:10:06.794174+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 1834.0, + "average_temperature": 30.8667, + "experience_temperature": 33.6867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:20:18.022649+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 1834.0, + "average_temperature": 30.8667, + "experience_temperature": 33.6867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:30:07.612428+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 1850.0, + "average_temperature": 31.1, + "experience_temperature": 32.8086, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:40:09.652102+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 1855.0, + "average_temperature": 31.5, + "experience_temperature": 33.64, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T08:50:06.181019+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.2, + "humidity": 78.8, + "water_total": 1867.0, + "average_temperature": 31.7667, + "experience_temperature": 32.1838, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:00:06.225510+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 75.2, + "water_total": 1877.0, + "average_temperature": 31.3, + "experience_temperature": 31.6686, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:10:07.322815+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.2, + "humidity": 74.9, + "water_total": 1885.0, + "average_temperature": 31.4667, + "experience_temperature": 31.1038, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:20:08.031695+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 74.7, + "water_total": 1891.0, + "average_temperature": 31.5, + "experience_temperature": 31.7686, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:30:07.240031+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 76.9, + "water_total": 1900.0, + "average_temperature": 31.8, + "experience_temperature": 32.5086, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:40:06.742900+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.5, + "humidity": 72.8, + "water_total": 1906.0, + "average_temperature": 32.2333, + "experience_temperature": 29.4362, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T09:50:06.465524+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 71.0, + "water_total": 1906.0, + "average_temperature": 32.4, + "experience_temperature": 27.9, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:00:07.214862+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 70.3, + "water_total": 1908.0, + "average_temperature": 32.4, + "experience_temperature": 27.0886, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:10:06.184109+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 67.9, + "water_total": 1908.0, + "average_temperature": 32.8333, + "experience_temperature": 27.7133, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:20:06.431913+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 67.0, + "water_total": 1911.0, + "average_temperature": 33.0667, + "experience_temperature": 27.0952, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:30:07.456321+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 68.0, + "water_total": 1911.0, + "average_temperature": 33.2333, + "experience_temperature": 27.4619, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:40:07.074786+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 66.8, + "water_total": 1912.0, + "average_temperature": 33.0, + "experience_temperature": 26.9886, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T10:50:06.436040+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 66.3, + "water_total": 1912.0, + "average_temperature": 33.2333, + "experience_temperature": 27.7933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:00:07.660668+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.2, + "humidity": 66.1, + "water_total": 1912.0, + "average_temperature": 33.4333, + "experience_temperature": 24.5962, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:10:06.430518+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 66.8, + "water_total": 1912.0, + "average_temperature": 33.5, + "experience_temperature": 27.4886, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:20:08.714466+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 66.4, + "water_total": 1912.0, + "average_temperature": 33.4, + "experience_temperature": 25.2943, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:30:08.472850+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 66.7, + "water_total": 1913.0, + "average_temperature": 33.4, + "experience_temperature": 26.6971, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:40:06.188043+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.0, + "humidity": 66.3, + "water_total": 1913.0, + "average_temperature": 33.6, + "experience_temperature": 26.1457, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T11:50:08.285986+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 66.2, + "water_total": 1913.0, + "average_temperature": 33.6333, + "experience_temperature": 25.4876, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:00:07.707214+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 66.2, + "water_total": 1913.0, + "average_temperature": 33.7333, + "experience_temperature": 27.6019, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:10:08.237272+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 64.4, + "water_total": 1913.0, + "average_temperature": 34.0667, + "experience_temperature": 26.9038, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:20:06.261378+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 64.4, + "water_total": 1913.0, + "average_temperature": 34.0667, + "experience_temperature": 26.9038, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:30:06.634576+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 64.2, + "water_total": 1913.0, + "average_temperature": 33.8667, + "experience_temperature": 28.0067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:40:06.340112+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 64.8, + "water_total": 1915.0, + "average_temperature": 34.0667, + "experience_temperature": 25.641, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T12:50:06.736029+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.5, + "humidity": 64.4, + "water_total": 1916.0, + "average_temperature": 34.3, + "experience_temperature": 23.1086, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:00:06.910129+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 63.2, + "water_total": 1918.0, + "average_temperature": 34.0, + "experience_temperature": 25.2543, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:10:08.681765+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.2, + "humidity": 63.9, + "water_total": 1918.0, + "average_temperature": 34.4, + "experience_temperature": 25.1229, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:20:07.571128+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.2, + "humidity": 63.5, + "water_total": 1918.0, + "average_temperature": 34.2333, + "experience_temperature": 24.8762, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:30:07.788658+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 64.7, + "water_total": 1918.0, + "average_temperature": 33.9667, + "experience_temperature": 26.8638, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:40:07.263855+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 64.8, + "water_total": 1920.0, + "average_temperature": 34.0667, + "experience_temperature": 25.641, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T13:50:06.973135+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 66.0, + "water_total": 1920.0, + "average_temperature": 34.0, + "experience_temperature": 27.1571, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T14:10:07.297573+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 65.6, + "water_total": 1920.0, + "average_temperature": 33.7333, + "experience_temperature": 28.1533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T14:20:07.259478+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.1, + "humidity": 64.7, + "water_total": 1921.0, + "average_temperature": 34.1, + "experience_temperature": 25.6543, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T14:30:06.315474+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.9, + "humidity": 65.5, + "water_total": 1922.0, + "average_temperature": 34.2, + "experience_temperature": 27.2571, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T14:40:07.215992+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.8, + "humidity": 66.2, + "water_total": 1922.0, + "average_temperature": 34.0333, + "experience_temperature": 27.9019, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T14:50:08.764779+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 1.2, + "humidity": 65.7, + "water_total": 1922.0, + "average_temperature": 34.1, + "experience_temperature": 25.1829, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T15:10:06.616515+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.7, + "humidity": 69.1, + "water_total": 1923.0, + "average_temperature": 33.1, + "experience_temperature": 28.22, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T15:20:06.642752+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.5, + "humidity": 72.0, + "water_total": 1923.0, + "average_temperature": 32.8667, + "experience_temperature": 29.9095, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T15:30:07.240481+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.6, + "humidity": 72.3, + "water_total": 1925.0, + "average_temperature": 32.4667, + "experience_temperature": 28.8981, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T15:40:06.951443+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.6, + "humidity": 72.9, + "water_total": 1925.0, + "average_temperature": 32.2333, + "experience_temperature": 28.7848, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T15:50:08.149085+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.2, + "humidity": 74.7, + "water_total": 1925.0, + "average_temperature": 32.2, + "experience_temperature": 31.7971, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T16:10:06.440794+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.2, + "humidity": 77.0, + "water_total": 1925.0, + "average_temperature": 32.1, + "experience_temperature": 32.1571, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T16:20:06.706539+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 79.5, + "water_total": 1925.0, + "average_temperature": 31.7, + "experience_temperature": 32.9286, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T16:30:06.835953+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.4, + "humidity": 79.7, + "water_total": 1927.0, + "average_temperature": 31.4, + "experience_temperature": 30.6543, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T16:40:06.698207+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.2, + "humidity": 79.3, + "water_total": 1927.0, + "average_temperature": 31.2, + "experience_temperature": 31.7171, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T16:50:07.748146+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 78.9, + "water_total": 1927.0, + "average_temperature": 30.7, + "experience_temperature": 32.48, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T17:10:07.002717+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 0.0, + "average_temperature": 31.1667, + "experience_temperature": 33.3867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T17:20:06.835492+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 30.8667, + "experience_temperature": 33.0067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T17:30:06.113281+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 33.04, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T17:40:06.616090+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 30.9, + "experience_temperature": 33.24, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T17:50:07.381644+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 0.0, + "average_temperature": 30.9667, + "experience_temperature": 33.5067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:00:07.468335+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 33.4333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:10:07.058369+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 33.2, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:20:09.520861+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 0.0, + "average_temperature": 31.0, + "experience_temperature": 33.54, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:30:09.085677+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 32.8133, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:40:06.976413+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.1, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 32.82, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T18:50:07.342297+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 32.7467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:00:06.553189+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 33.2133, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:10:08.239572+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 33.78, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:20:06.763767+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 32.1019, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:30:07.722800+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.5, + "water_total": 2.0, + "average_temperature": 30.4667, + "experience_temperature": 33.1667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:40:06.255100+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 81.8, + "water_total": 2.0, + "average_temperature": 30.5333, + "experience_temperature": 32.2219, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T19:50:07.100702+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 2.0, + "average_temperature": 30.6333, + "experience_temperature": 33.2733, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:00:08.449806+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 2.0, + "average_temperature": 30.6333, + "experience_temperature": 33.4133, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:10:06.447930+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.5, + "water_total": 8.0, + "average_temperature": 30.5333, + "experience_temperature": 33.2333, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:20:06.363832+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 8.0, + "average_temperature": 30.8667, + "experience_temperature": 33.7667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:30:06.482578+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 8.0, + "average_temperature": 30.4667, + "experience_temperature": 33.3667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:40:07.195832+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 8.0, + "average_temperature": 30.5333, + "experience_temperature": 33.1533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T20:50:07.235663+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 8.0, + "average_temperature": 30.5667, + "experience_temperature": 33.1667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:00:07.381165+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 8.0, + "average_temperature": 30.4667, + "experience_temperature": 33.0867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:10:06.530341+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 8.0, + "average_temperature": 30.4667, + "experience_temperature": 33.2067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:20:06.671580+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 8.0, + "average_temperature": 30.2333, + "experience_temperature": 32.9933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:30:07.708510+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 8.0, + "average_temperature": 30.4333, + "experience_temperature": 33.4933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:40:07.105495+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 8.0, + "average_temperature": 30.1667, + "experience_temperature": 32.9667, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T21:50:07.460235+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 8.0, + "average_temperature": 30.2333, + "experience_temperature": 33.2533, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:00:08.644196+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 30.0, + "experience_temperature": 32.84, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:10:06.154039+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 10.0, + "average_temperature": 30.1333, + "experience_temperature": 32.9933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:20:06.495967+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.9667, + "experience_temperature": 32.7067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:30:06.782129+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 86.5, + "water_total": 10.0, + "average_temperature": 30.1, + "experience_temperature": 33.4, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:40:06.251679+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 10.0, + "average_temperature": 29.9, + "experience_temperature": 32.8, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T22:50:06.698291+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 10.0, + "average_temperature": 30.1667, + "experience_temperature": 33.0467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:00:06.416192+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 10.0, + "average_temperature": 30.0667, + "experience_temperature": 32.9467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:10:06.369152+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.1, + "humidity": 84.1, + "water_total": 10.0, + "average_temperature": 30.5667, + "experience_temperature": 32.7152, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:20:05.769660+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 10.0, + "average_temperature": 29.7667, + "experience_temperature": 32.5867, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:30:06.326789+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 10.0, + "average_temperature": 29.5333, + "experience_temperature": 32.4933, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:40:07.107040+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 10.0, + "average_temperature": 29.4667, + "experience_temperature": 32.3467, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-30T23:50:05.520690+07:00", + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 10.0, + "average_temperature": 29.5667, + "experience_temperature": 32.5067, + "chill_factor": 6.7143 + }, + { + "timestamp": "2026-05-31T00:00:05.640087+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 10.0, + "average_temperature": 29.4667, + "experience_temperature": 32.4867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T00:10:06.884397+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 29.3, + "experience_temperature": 32.22, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T00:20:05.582814+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.0867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T00:30:05.562066+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 29.0333, + "experience_temperature": 31.9533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T00:40:05.523826+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 10.0, + "average_temperature": 29.1, + "experience_temperature": 32.2, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T00:50:06.702063+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 31.8333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:00:07.953275+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.6, + "water_total": 10.0, + "average_temperature": 29.1333, + "experience_temperature": 32.4533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:10:05.956271+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 10.0, + "average_temperature": 28.8667, + "experience_temperature": 31.8867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:20:05.136935+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 32.1533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:30:06.067884+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 32.1533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:40:05.398968+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.7, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 32.3067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T01:50:05.620605+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 10.0, + "average_temperature": 28.8667, + "experience_temperature": 31.9067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:00:05.746088+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 32.1533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:10:05.761853+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 32.1533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:20:05.242281+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 29.7667, + "experience_temperature": 32.0295, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:30:07.764393+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.1, + "experience_temperature": 31.84, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:40:05.640363+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.2267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T02:50:05.794499+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.2667, + "experience_temperature": 32.1067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:00:07.649983+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.8, + "water_total": 10.0, + "average_temperature": 29.5667, + "experience_temperature": 32.7267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:10:05.663972+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 10.0, + "average_temperature": 29.1, + "experience_temperature": 31.78, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:20:05.966772+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 31.7667, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:30:05.522352+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 10.0, + "average_temperature": 28.7333, + "experience_temperature": 31.1733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:40:06.099057+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 31.8867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T03:50:05.326084+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 31.5467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:00:06.357834+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 10.0, + "average_temperature": 29.0333, + "experience_temperature": 31.8133, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:10:05.899172+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 10.0, + "average_temperature": 28.7333, + "experience_temperature": 31.4533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:20:07.520223+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 10.0, + "average_temperature": 28.7667, + "experience_temperature": 31.6667, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:30:05.486911+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 10.0, + "average_temperature": 28.8667, + "experience_temperature": 31.8467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:40:05.351883+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 10.0, + "average_temperature": 29.1, + "experience_temperature": 32.04, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T04:50:05.632337+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 10.0, + "average_temperature": 29.2333, + "experience_temperature": 31.8933, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:00:05.309305+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 32.0867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:10:06.888437+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 10.0, + "average_temperature": 28.6667, + "experience_temperature": 31.5467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:20:06.364122+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 10.0, + "average_temperature": 29.9667, + "experience_temperature": 32.9867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:30:05.475915+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 10.0, + "average_temperature": 29.7, + "experience_temperature": 32.1, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:40:06.104344+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 31.9867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T05:50:05.753738+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 10.0, + "average_temperature": 30.1, + "experience_temperature": 32.42, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:00:06.573363+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.7, + "experience_temperature": 32.44, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:10:05.473417+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 10.0, + "average_temperature": 29.4667, + "experience_temperature": 31.9867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:20:07.674394+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 10.0, + "average_temperature": 29.3333, + "experience_temperature": 32.3133, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:30:07.155295+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.0667, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:40:06.567005+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.1, + "water_total": 10.0, + "average_temperature": 30.3667, + "experience_temperature": 33.5867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T06:50:05.724050+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 10.0, + "average_temperature": 29.6667, + "experience_temperature": 32.1267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:00:07.371184+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 10.0, + "average_temperature": 29.6333, + "experience_temperature": 32.4933, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:10:05.711764+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 10.0, + "average_temperature": 29.3667, + "experience_temperature": 32.0867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:20:06.458591+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 10.0, + "average_temperature": 29.3667, + "experience_temperature": 32.4667, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:30:07.357799+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 10.0, + "average_temperature": 29.3, + "experience_temperature": 32.4, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:40:05.586232+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 10.0, + "average_temperature": 29.7, + "experience_temperature": 32.76, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T07:50:06.405682+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 10.0, + "average_temperature": 29.3333, + "experience_temperature": 31.9933, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:00:06.062314+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.7, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 33.0733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:10:05.983478+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 10.0, + "average_temperature": 29.7667, + "experience_temperature": 32.4467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:20:06.118450+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 84.8, + "water_total": 10.0, + "average_temperature": 29.5667, + "experience_temperature": 31.8695, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:30:06.055230+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 10.0, + "average_temperature": 29.6, + "experience_temperature": 32.46, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:40:06.761030+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 33.1333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T08:50:06.267485+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 10.0, + "average_temperature": 30.0, + "experience_temperature": 32.52, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:00:07.142530+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 84.7, + "water_total": 10.0, + "average_temperature": 30.5, + "experience_temperature": 32.1257, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:10:06.183735+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 82.7, + "water_total": 10.0, + "average_temperature": 30.6333, + "experience_temperature": 31.859, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:20:07.101560+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 82.0, + "water_total": 10.0, + "average_temperature": 30.7667, + "experience_temperature": 32.5095, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:30:07.338272+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 10.0, + "average_temperature": 30.7667, + "experience_temperature": 33.1467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:40:07.129466+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 10.0, + "average_temperature": 31.1333, + "experience_temperature": 31.919, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T09:50:06.679575+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 10.0, + "average_temperature": 31.1, + "experience_temperature": 33.32, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:00:06.369246+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 79.0, + "water_total": 10.0, + "average_temperature": 31.1333, + "experience_temperature": 31.619, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:10:07.135658+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 10.0, + "average_temperature": 31.2, + "experience_temperature": 31.2657, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:20:06.021515+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 77.4, + "water_total": 10.0, + "average_temperature": 31.1, + "experience_temperature": 31.2657, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:30:06.225287+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 77.1, + "water_total": 10.0, + "average_temperature": 31.1, + "experience_temperature": 31.2057, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:40:06.499350+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 79.9, + "water_total": 10.0, + "average_temperature": 31.5667, + "experience_temperature": 32.8895, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T10:50:06.323658+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 78.5, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 32.3857, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:00:05.924365+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 77.1, + "water_total": 10.0, + "average_temperature": 31.9667, + "experience_temperature": 31.4152, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:10:07.315067+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 75.3, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 31.0886, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:20:08.265387+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 73.5, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 30.7286, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:30:06.322573+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 74.2, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.9305, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:40:06.754229+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.5, + "humidity": 73.4, + "water_total": 10.0, + "average_temperature": 31.9667, + "experience_temperature": 29.361, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T11:50:09.151275+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.7, + "humidity": 73.7, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.1733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:00:07.944158+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.7, + "humidity": 73.7, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.1733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:10:06.513925+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 75.3, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 29.1505, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:20:07.088253+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 74.0, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.8905, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:30:06.205452+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 75.6, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 29.2105, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:40:05.997453+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.4, + "humidity": 75.4, + "water_total": 10.0, + "average_temperature": 31.9667, + "experience_temperature": 30.4181, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T12:50:06.741024+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 75.6, + "water_total": 10.0, + "average_temperature": 32.1333, + "experience_temperature": 29.3105, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:00:06.975585+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 74.4, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.9705, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:10:07.008137+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 75.0, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 31.0286, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:20:07.958463+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.5, + "humidity": 75.1, + "water_total": 10.0, + "average_temperature": 32.0667, + "experience_temperature": 29.801, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:30:06.402745+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.4, + "humidity": 75.4, + "water_total": 10.0, + "average_temperature": 32.1333, + "experience_temperature": 30.5848, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:40:06.396292+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 73.8, + "water_total": 10.0, + "average_temperature": 32.2, + "experience_temperature": 29.0171, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T13:50:06.581773+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 73.9, + "water_total": 10.0, + "average_temperature": 32.3667, + "experience_temperature": 29.2038, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T14:10:06.924109+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.7, + "humidity": 74.9, + "water_total": 10.0, + "average_temperature": 32.4, + "experience_temperature": 28.78, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T14:20:07.073893+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.8, + "humidity": 72.3, + "water_total": 10.0, + "average_temperature": 32.2667, + "experience_temperature": 27.4695, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T14:30:06.817566+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.7, + "humidity": 73.6, + "water_total": 10.0, + "average_temperature": 32.0667, + "experience_temperature": 28.1867, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T14:40:06.818114+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.6, + "humidity": 75.6, + "water_total": 10.0, + "average_temperature": 32.0667, + "experience_temperature": 29.2438, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T14:50:06.507939+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 75.8, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 31.1886, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T15:10:06.977148+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 76.2, + "water_total": 10.0, + "average_temperature": 31.9333, + "experience_temperature": 31.859, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T15:20:07.272102+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 76.5, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 31.3286, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T15:30:07.218631+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.7, + "humidity": 75.7, + "water_total": 10.0, + "average_temperature": 32.0333, + "experience_temperature": 28.5733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T15:40:06.997308+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 76.2, + "water_total": 10.0, + "average_temperature": 32.0, + "experience_temperature": 31.9257, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T15:50:08.210715+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 77.0, + "water_total": 14.0, + "average_temperature": 31.8, + "experience_temperature": 32.5429, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T16:10:07.008245+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 77.4, + "water_total": 14.0, + "average_temperature": 31.6333, + "experience_temperature": 31.1419, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T16:20:08.974855+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 14.0, + "average_temperature": 31.5, + "experience_temperature": 31.5657, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T16:30:06.763200+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 77.5, + "water_total": 14.0, + "average_temperature": 31.4667, + "experience_temperature": 31.6524, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T16:40:06.795103+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 78.0, + "water_total": 14.0, + "average_temperature": 31.1667, + "experience_temperature": 30.7952, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T16:50:06.834700+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 78.7, + "water_total": 14.0, + "average_temperature": 31.3, + "experience_temperature": 31.0686, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T17:10:06.648636+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.3, + "humidity": 77.9, + "water_total": 0.0, + "average_temperature": 31.1667, + "experience_temperature": 30.7752, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T17:20:06.151962+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 77.6, + "water_total": 0.0, + "average_temperature": 31.0667, + "experience_temperature": 31.9295, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T17:30:06.885201+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 78.4, + "water_total": 0.0, + "average_temperature": 31.0, + "experience_temperature": 32.68, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T17:40:06.707144+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 33.0133, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T17:50:09.103256+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 80.2, + "water_total": 0.0, + "average_temperature": 30.5667, + "experience_temperature": 32.6067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:00:07.234853+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 80.9, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 32.1562, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:10:11.405458+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 81.2, + "water_total": 4.0, + "average_temperature": 30.2333, + "experience_temperature": 31.8162, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:20:06.469780+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.3, + "water_total": 5.0, + "average_temperature": 30.0333, + "experience_temperature": 32.2933, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:30:07.008828+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.1, + "humidity": 81.3, + "water_total": 5.0, + "average_temperature": 30.2333, + "experience_temperature": 31.8362, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:40:06.870139+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 10.0, + "average_temperature": 30.0, + "experience_temperature": 32.22, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T18:50:06.494468+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 10.0, + "average_temperature": 30.2333, + "experience_temperature": 32.7333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:00:07.103312+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 10.0, + "average_temperature": 30.0667, + "experience_temperature": 32.5267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:10:06.239837+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 30.2667, + "experience_temperature": 33.0067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:20:06.542427+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 10.0, + "average_temperature": 30.0667, + "experience_temperature": 32.5667, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:30:06.544063+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 10.0, + "average_temperature": 30.3, + "experience_temperature": 32.96, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:40:06.742384+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 10.0, + "average_temperature": 29.8, + "experience_temperature": 32.24, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T19:50:08.139136+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.2, + "humidity": 83.0, + "water_total": 10.0, + "average_temperature": 30.0333, + "experience_temperature": 31.319, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:00:07.053521+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 32.3333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:10:06.272774+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 32.3333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:20:06.251881+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 10.0, + "average_temperature": 30.1333, + "experience_temperature": 32.8133, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:30:07.955626+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 10.0, + "average_temperature": 30.4667, + "experience_temperature": 33.2267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:40:07.163954+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 10.0, + "average_temperature": 30.3333, + "experience_temperature": 33.0533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T20:50:06.640722+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 10.0, + "average_temperature": 30.3667, + "experience_temperature": 33.3467, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:00:07.173170+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 32.6533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:10:05.834277+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 30.2333, + "experience_temperature": 33.1533, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:20:08.537664+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 30.1333, + "experience_temperature": 32.9733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:30:05.948692+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 10.0, + "average_temperature": 30.1, + "experience_temperature": 33.1, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:40:05.507126+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.8667, + "experience_temperature": 32.7067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T21:50:06.456623+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 10.0, + "average_temperature": 30.0333, + "experience_temperature": 32.9733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:00:05.877926+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.8667, + "experience_temperature": 32.6067, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:10:08.117952+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.9333, + "experience_temperature": 32.7733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:20:05.680484+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.5, + "water_total": 10.0, + "average_temperature": 29.6333, + "experience_temperature": 32.3333, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:30:05.877067+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 10.0, + "average_temperature": 29.7, + "experience_temperature": 32.48, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:40:05.868098+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 10.0, + "average_temperature": 29.4333, + "experience_temperature": 32.0933, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T22:50:06.520136+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 10.0, + "average_temperature": 29.6, + "experience_temperature": 32.56, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:00:06.359205+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 10.0, + "average_temperature": 29.2333, + "experience_temperature": 32.4133, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:10:07.147359+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 10.0, + "average_temperature": 29.2, + "experience_temperature": 32.18, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:20:07.439485+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 10.0, + "average_temperature": 29.5667, + "experience_temperature": 32.6267, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:30:05.285803+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.8333, + "experience_temperature": 32.6733, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:40:05.490150+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.3, + "experience_temperature": 32.04, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-05-31T23:50:06.278389+07:00", + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.3, + "experience_temperature": 32.04, + "chill_factor": 6.5714 + }, + { + "timestamp": "2026-06-01T00:00:05.824461+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.0867, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T00:10:07.108110+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.4, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 32.0467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T00:20:05.872340+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 30.1, + "experience_temperature": 32.84, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T00:30:06.736533+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 10.0, + "average_temperature": 29.7, + "experience_temperature": 32.7, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T00:40:05.749443+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 10.0, + "average_temperature": 29.2667, + "experience_temperature": 32.5067, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T00:50:06.596517+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.4, + "water_total": 10.0, + "average_temperature": 28.9333, + "experience_temperature": 32.0133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:00:05.466313+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 83.1, + "water_total": 10.0, + "average_temperature": 29.8333, + "experience_temperature": 31.8105, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:10:05.916122+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 10.0, + "average_temperature": 29.5333, + "experience_temperature": 32.6333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:20:07.431625+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 10.0, + "average_temperature": 29.6, + "experience_temperature": 30.8743, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:30:06.250628+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 10.0, + "average_temperature": 29.6, + "experience_temperature": 30.8743, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:40:06.381531+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.4, + "water_total": 10.0, + "average_temperature": 28.9667, + "experience_temperature": 32.0467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T01:50:05.992574+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.0067, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:00:05.787977+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 10.0, + "average_temperature": 30.2333, + "experience_temperature": 32.8333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:10:06.275997+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 10.0, + "average_temperature": 29.1667, + "experience_temperature": 32.1267, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:20:06.650307+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 30.3, + "experience_temperature": 33.22, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:30:05.651887+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 10.0, + "average_temperature": 30.3, + "experience_temperature": 33.22, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:40:05.446320+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 10.0, + "average_temperature": 29.8, + "experience_temperature": 32.28, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T02:50:05.506966+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 10.0, + "average_temperature": 29.8333, + "experience_temperature": 32.6733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:00:05.810526+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 12.0, + "average_temperature": 29.6667, + "experience_temperature": 32.3267, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:10:05.589290+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 12.0, + "average_temperature": 29.0333, + "experience_temperature": 31.9333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:20:05.839472+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.8, + "water_total": 12.0, + "average_temperature": 29.5, + "experience_temperature": 31.86, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:30:05.754244+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.5, + "water_total": 12.0, + "average_temperature": 29.9333, + "experience_temperature": 32.6333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:40:06.176676+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 12.0, + "average_temperature": 29.4, + "experience_temperature": 32.04, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T03:50:07.169157+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 12.0, + "average_temperature": 30.2667, + "experience_temperature": 33.0467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:00:05.799346+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.0, + "water_total": 12.0, + "average_temperature": 29.0667, + "experience_temperature": 31.4667, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:10:06.133684+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 12.0, + "average_temperature": 30.0667, + "experience_temperature": 32.4467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:20:05.527401+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 12.0, + "average_temperature": 29.2, + "experience_temperature": 31.76, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:30:05.700541+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 12.0, + "average_temperature": 29.7333, + "experience_temperature": 32.2533, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:40:06.248096+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 12.0, + "average_temperature": 29.2333, + "experience_temperature": 31.8933, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T04:50:05.804724+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 14.0, + "average_temperature": 29.6, + "experience_temperature": 32.08, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:00:06.048454+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 14.0, + "average_temperature": 29.3, + "experience_temperature": 32.14, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:10:06.220686+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 14.0, + "average_temperature": 28.9, + "experience_temperature": 31.68, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:20:05.781985+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 14.0, + "average_temperature": 29.4, + "experience_temperature": 31.72, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:30:06.367913+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 14.0, + "average_temperature": 29.8333, + "experience_temperature": 32.6533, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:40:05.957697+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 14.0, + "average_temperature": 29.0667, + "experience_temperature": 31.7067, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T05:50:06.096242+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 16.0, + "average_temperature": 29.8333, + "experience_temperature": 32.3133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:00:06.541241+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 16.0, + "average_temperature": 29.3333, + "experience_temperature": 32.1733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:10:05.775000+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 16.0, + "average_temperature": 28.8333, + "experience_temperature": 31.4333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:20:06.363823+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 16.0, + "average_temperature": 29.2, + "experience_temperature": 31.66, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:30:06.271382+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 16.0, + "average_temperature": 29.6667, + "experience_temperature": 32.4867, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:40:08.025515+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 16.0, + "average_temperature": 29.0333, + "experience_temperature": 31.5133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T06:50:06.003206+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.0, + "water_total": 16.0, + "average_temperature": 29.5667, + "experience_temperature": 32.1667, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:00:06.085753+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.9, + "water_total": 16.0, + "average_temperature": 29.0, + "experience_temperature": 31.58, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:10:06.188554+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 16.0, + "average_temperature": 29.5667, + "experience_temperature": 32.3467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:20:06.517176+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 16.0, + "average_temperature": 29.3, + "experience_temperature": 31.84, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:30:06.817105+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 16.0, + "average_temperature": 29.3333, + "experience_temperature": 32.3733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:40:05.525283+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 16.0, + "average_temperature": 29.8, + "experience_temperature": 32.54, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T07:50:05.913730+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 16.0, + "average_temperature": 30.0, + "experience_temperature": 33.06, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:00:09.600046+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 82.9, + "water_total": 20.0, + "average_temperature": 30.4, + "experience_temperature": 32.3371, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:10:05.713229+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 82.0, + "water_total": 20.0, + "average_temperature": 30.6, + "experience_temperature": 32.3571, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:20:05.907464+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 20.0, + "average_temperature": 30.6667, + "experience_temperature": 33.1067, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:30:06.609986+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 20.0, + "average_temperature": 31.1, + "experience_temperature": 31.9943, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:40:05.798732+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 78.2, + "water_total": 20.0, + "average_temperature": 31.0, + "experience_temperature": 31.3543, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T08:50:07.009375+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 80.2, + "water_total": 20.0, + "average_temperature": 31.3, + "experience_temperature": 32.0543, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:00:08.271921+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 76.3, + "water_total": 24.0, + "average_temperature": 31.7, + "experience_temperature": 31.6743, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:10:05.599771+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 74.5, + "water_total": 24.0, + "average_temperature": 31.7667, + "experience_temperature": 30.7381, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:20:06.827802+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.5, + "humidity": 73.6, + "water_total": 24.0, + "average_temperature": 31.8667, + "experience_temperature": 29.3724, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:30:06.511924+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 74.8, + "water_total": 24.0, + "average_temperature": 31.8, + "experience_temperature": 31.4743, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:40:06.393315+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 71.8, + "water_total": 24.0, + "average_temperature": 31.8667, + "experience_temperature": 27.7267, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T09:50:06.480730+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.6, + "humidity": 72.3, + "water_total": 24.0, + "average_temperature": 32.1667, + "experience_temperature": 28.7695, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:00:05.857824+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.6, + "humidity": 68.3, + "water_total": 24.0, + "average_temperature": 32.4333, + "experience_temperature": 28.2362, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:10:06.883301+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 69.5, + "water_total": 26.0, + "average_temperature": 32.6333, + "experience_temperature": 28.0333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:20:06.157389+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 69.5, + "water_total": 26.0, + "average_temperature": 32.6333, + "experience_temperature": 28.0333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:30:05.748915+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.6, + "humidity": 72.0, + "water_total": 26.0, + "average_temperature": 32.6667, + "experience_temperature": 29.2095, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:40:06.127291+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.8, + "humidity": 69.6, + "water_total": 26.0, + "average_temperature": 32.8, + "experience_temperature": 27.5771, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T10:50:06.662344+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 70.6, + "water_total": 26.0, + "average_temperature": 32.8333, + "experience_temperature": 28.4533, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:00:08.893418+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 70.4, + "water_total": 26.0, + "average_temperature": 32.8, + "experience_temperature": 28.38, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:10:06.778538+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.9, + "humidity": 68.9, + "water_total": 26.0, + "average_temperature": 32.8333, + "experience_temperature": 26.8276, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:20:07.276634+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.0, + "humidity": 71.6, + "water_total": 26.0, + "average_temperature": 33.2, + "experience_temperature": 27.0914, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:30:06.846301+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 70.2, + "water_total": 26.0, + "average_temperature": 33.3, + "experience_temperature": 25.6257, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:40:06.088593+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.1, + "humidity": 68.9, + "water_total": 26.0, + "average_temperature": 33.3667, + "experience_temperature": 26.0752, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T11:50:06.397898+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.8, + "humidity": 70.3, + "water_total": 26.0, + "average_temperature": 32.8, + "experience_temperature": 27.7171, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:00:06.492980+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 70.9, + "water_total": 26.0, + "average_temperature": 32.7333, + "experience_temperature": 28.4133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:10:06.300362+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 70.9, + "water_total": 26.0, + "average_temperature": 33.0333, + "experience_temperature": 25.499, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:20:06.067958+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 70.1, + "water_total": 28.0, + "average_temperature": 32.7667, + "experience_temperature": 28.2867, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:30:05.714980+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 71.9, + "water_total": 28.0, + "average_temperature": 32.9333, + "experience_temperature": 25.599, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:40:06.791563+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 69.8, + "water_total": 29.0, + "average_temperature": 33.0667, + "experience_temperature": 25.3124, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T12:50:07.230029+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.8, + "humidity": 71.0, + "water_total": 29.0, + "average_temperature": 32.7, + "experience_temperature": 27.7571, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:00:05.644228+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.6, + "humidity": 70.5, + "water_total": 29.0, + "average_temperature": 32.8, + "experience_temperature": 29.0429, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:10:05.715758+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 69.1, + "water_total": 34.0, + "average_temperature": 32.9, + "experience_temperature": 25.0057, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:20:06.332246+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 69.3, + "water_total": 38.0, + "average_temperature": 32.9333, + "experience_temperature": 25.079, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:30:05.945127+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.9, + "humidity": 69.4, + "water_total": 41.0, + "average_temperature": 33.1667, + "experience_temperature": 27.261, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:40:06.383886+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 1.2, + "humidity": 70.9, + "water_total": 43.0, + "average_temperature": 33.1, + "experience_temperature": 25.5657, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T13:50:05.895289+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.7, + "humidity": 72.2, + "water_total": 51.0, + "average_temperature": 32.8, + "experience_temperature": 28.74, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T14:10:06.495009+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.9, + "humidity": 75.9, + "water_total": 65.0, + "average_temperature": 31.8333, + "experience_temperature": 27.2276, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T14:20:07.615438+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.6, + "humidity": 76.8, + "water_total": 78.0, + "average_temperature": 31.9, + "experience_temperature": 29.4029, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T14:30:07.478858+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.8, + "humidity": 75.6, + "water_total": 95.0, + "average_temperature": 31.8333, + "experience_temperature": 27.8105, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T14:40:07.483672+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 75.4, + "water_total": 118.0, + "average_temperature": 31.7667, + "experience_temperature": 31.561, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T14:50:06.737868+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.4, + "humidity": 76.4, + "water_total": 155.0, + "average_temperature": 31.8, + "experience_temperature": 30.5086, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T15:10:06.163742+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 77.7, + "water_total": 222.0, + "average_temperature": 31.7667, + "experience_temperature": 32.021, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T15:20:05.823965+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 78.7, + "water_total": 254.0, + "average_temperature": 31.8333, + "experience_temperature": 31.6448, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T15:30:06.053567+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 77.1, + "water_total": 288.0, + "average_temperature": 31.6667, + "experience_temperature": 31.1581, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T15:40:05.893642+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 77.1, + "water_total": 288.0, + "average_temperature": 31.6667, + "experience_temperature": 31.1581, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T15:50:06.538289+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 78.0, + "water_total": 351.0, + "average_temperature": 31.7, + "experience_temperature": 32.0143, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T16:10:06.005655+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 78.7, + "water_total": 422.0, + "average_temperature": 31.6, + "experience_temperature": 32.0543, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T16:20:06.164406+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 78.5, + "water_total": 458.0, + "average_temperature": 31.5667, + "experience_temperature": 31.981, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T16:30:06.493659+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 79.7, + "water_total": 486.0, + "average_temperature": 31.6333, + "experience_temperature": 31.6448, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T16:40:06.324315+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 79.0, + "water_total": 521.0, + "average_temperature": 31.4667, + "experience_temperature": 31.981, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T16:50:06.242458+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 79.8, + "water_total": 554.0, + "average_temperature": 31.5, + "experience_temperature": 32.1743, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T17:10:06.594812+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 76.0, + "water_total": 591.0, + "average_temperature": 31.7, + "experience_temperature": 31.6143, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T17:20:06.247887+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 81.7, + "water_total": 69.0, + "average_temperature": 31.2333, + "experience_temperature": 32.2876, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T17:30:08.616992+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.4, + "water_total": 99.0, + "average_temperature": 30.9, + "experience_temperature": 33.18, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T17:40:06.613626+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 129.0, + "average_temperature": 30.8667, + "experience_temperature": 33.0667, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T17:50:07.394224+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 79.2, + "water_total": 157.0, + "average_temperature": 30.7, + "experience_temperature": 31.2543, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:00:06.842195+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 79.7, + "water_total": 194.0, + "average_temperature": 30.5667, + "experience_temperature": 31.8638, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:10:08.521374+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 80.0, + "water_total": 222.0, + "average_temperature": 30.6333, + "experience_temperature": 31.3476, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:20:08.409317+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 80.4, + "water_total": 260.0, + "average_temperature": 30.4667, + "experience_temperature": 31.261, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:30:07.326499+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 284.0, + "average_temperature": 30.3667, + "experience_temperature": 32.5867, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:40:06.543185+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 321.0, + "average_temperature": 30.4667, + "experience_temperature": 32.7667, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T18:50:06.769037+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 360.0, + "average_temperature": 30.5, + "experience_temperature": 31.5143, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:00:07.075005+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 80.9, + "water_total": 396.0, + "average_temperature": 30.2, + "experience_temperature": 30.4514, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:10:07.096927+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 81.1, + "water_total": 427.0, + "average_temperature": 30.1333, + "experience_temperature": 31.7105, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:20:06.260010+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 81.5, + "water_total": 468.0, + "average_temperature": 30.3333, + "experience_temperature": 31.9905, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:30:06.098493+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 80.8, + "water_total": 501.0, + "average_temperature": 30.0333, + "experience_temperature": 32.1933, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:40:07.771776+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 80.3, + "water_total": 538.0, + "average_temperature": 29.8333, + "experience_temperature": 30.6076, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T19:50:07.495686+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 562.0, + "average_temperature": 29.7333, + "experience_temperature": 32.3533, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:00:07.817421+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.3, + "humidity": 81.0, + "water_total": 588.0, + "average_temperature": 29.7667, + "experience_temperature": 30.0381, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:10:07.292234+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 615.0, + "average_temperature": 29.7, + "experience_temperature": 32.14, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:20:06.557444+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 80.9, + "water_total": 645.0, + "average_temperature": 29.5333, + "experience_temperature": 31.7133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:30:06.503659+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 674.0, + "average_temperature": 29.5333, + "experience_temperature": 32.0533, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:40:06.666402+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 82.6, + "water_total": 701.0, + "average_temperature": 29.5, + "experience_temperature": 30.7343, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T20:50:07.080832+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 723.0, + "average_temperature": 29.5333, + "experience_temperature": 32.0133, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:00:05.689675+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 83.9, + "water_total": 757.0, + "average_temperature": 29.9333, + "experience_temperature": 32.0705, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:10:07.024751+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.3, + "water_total": 793.0, + "average_temperature": 30.3333, + "experience_temperature": 32.9933, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:20:06.413178+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 822.0, + "average_temperature": 30.0, + "experience_temperature": 32.56, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:30:10.827479+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 81.6, + "water_total": 845.0, + "average_temperature": 29.9333, + "experience_temperature": 30.9676, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:40:06.323070+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 877.0, + "average_temperature": 29.8333, + "experience_temperature": 32.3933, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T21:50:06.549613+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 900.0, + "average_temperature": 29.8333, + "experience_temperature": 31.5705, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:00:07.184717+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 928.0, + "average_temperature": 29.8667, + "experience_temperature": 32.5067, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:10:06.714880+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.2, + "humidity": 83.2, + "water_total": 957.0, + "average_temperature": 29.7, + "experience_temperature": 31.0543, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:20:06.776952+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 978.0, + "average_temperature": 29.5333, + "experience_temperature": 32.2733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:30:06.325119+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1009.0, + "average_temperature": 29.6667, + "experience_temperature": 32.5467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:40:08.223449+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 1044.0, + "average_temperature": 29.7333, + "experience_temperature": 32.7333, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T22:50:06.341841+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 1059.0, + "average_temperature": 29.4, + "experience_temperature": 32.04, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:00:06.356103+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1074.0, + "average_temperature": 29.2667, + "experience_temperature": 32.1467, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:10:07.314711+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 1090.0, + "average_temperature": 29.2, + "experience_temperature": 32.06, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:20:06.394103+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 1100.0, + "average_temperature": 29.1333, + "experience_temperature": 31.9733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:30:07.246184+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.2, + "water_total": 1100.0, + "average_temperature": 29.1333, + "experience_temperature": 31.9733, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:40:07.003987+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 1126.0, + "average_temperature": 29.1333, + "experience_temperature": 32.0933, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-01T23:50:07.695660+07:00", + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1139.0, + "average_temperature": 29.1, + "experience_temperature": 31.98, + "chill_factor": 6.4286 + }, + { + "timestamp": "2026-06-02T00:00:06.186083+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.7, + "water_total": 1148.0, + "average_temperature": 29.1, + "experience_temperature": 32.24, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T00:10:06.943503+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 1163.0, + "average_temperature": 28.7667, + "experience_temperature": 31.7667, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T00:20:06.712582+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 1173.0, + "average_temperature": 28.7333, + "experience_temperature": 31.8533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T00:30:09.424052+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 1182.0, + "average_temperature": 28.6333, + "experience_temperature": 31.6533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T00:40:06.452715+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 1196.0, + "average_temperature": 28.6, + "experience_temperature": 31.8, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T00:50:07.015649+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 1206.0, + "average_temperature": 28.4333, + "experience_temperature": 31.4533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:00:06.782249+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 1216.0, + "average_temperature": 28.3667, + "experience_temperature": 31.4867, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:10:07.175627+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 1229.0, + "average_temperature": 28.3667, + "experience_temperature": 31.4267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:20:06.555939+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.6, + "water_total": 1238.0, + "average_temperature": 28.3333, + "experience_temperature": 31.6533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:30:06.722813+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.3, + "water_total": 1254.0, + "average_temperature": 28.3667, + "experience_temperature": 31.4267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:40:06.483234+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 1264.0, + "average_temperature": 28.3667, + "experience_temperature": 31.5667, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T01:50:06.662487+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 1275.0, + "average_temperature": 28.3333, + "experience_temperature": 31.5733, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:00:06.940921+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 1290.0, + "average_temperature": 28.3, + "experience_temperature": 31.54, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:10:06.719610+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.8, + "water_total": 1316.0, + "average_temperature": 28.7667, + "experience_temperature": 32.1267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:20:07.205350+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 1366.0, + "average_temperature": 29.0667, + "experience_temperature": 32.2467, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:30:06.367011+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 1403.0, + "average_temperature": 28.5, + "experience_temperature": 31.7, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:40:07.413252+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 1432.0, + "average_temperature": 28.2667, + "experience_temperature": 31.3867, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T02:50:07.523513+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 1459.0, + "average_temperature": 28.4, + "experience_temperature": 31.44, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:00:05.739398+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 85.0, + "water_total": 1481.0, + "average_temperature": 28.5333, + "experience_temperature": 30.9048, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:10:06.637638+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 1535.0, + "average_temperature": 28.8667, + "experience_temperature": 31.8267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:20:09.776593+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 1561.0, + "average_temperature": 28.3667, + "experience_temperature": 31.1667, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:30:06.821647+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 83.6, + "water_total": 1577.0, + "average_temperature": 28.1, + "experience_temperature": 30.1914, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:40:06.501224+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1604.0, + "average_temperature": 28.1667, + "experience_temperature": 31.0467, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T03:50:06.667818+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 1640.0, + "average_temperature": 28.4, + "experience_temperature": 31.02, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:00:05.893957+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 1663.0, + "average_temperature": 28.1333, + "experience_temperature": 30.8133, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:10:06.501435+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 1693.0, + "average_temperature": 27.8667, + "experience_temperature": 30.5867, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:20:06.428270+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 1716.0, + "average_temperature": 27.7333, + "experience_temperature": 30.3733, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:30:07.451985+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 1736.0, + "average_temperature": 27.7333, + "experience_temperature": 30.4733, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:40:06.783406+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 1764.0, + "average_temperature": 27.9333, + "experience_temperature": 30.9133, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T04:50:06.127935+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 83.5, + "water_total": 1802.0, + "average_temperature": 28.1667, + "experience_temperature": 30.2381, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:00:06.700470+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1836.0, + "average_temperature": 27.7333, + "experience_temperature": 30.6133, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:10:08.127414+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 1862.0, + "average_temperature": 27.6333, + "experience_temperature": 30.5533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:20:06.508202+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 1879.0, + "average_temperature": 27.6667, + "experience_temperature": 30.5267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:30:07.025495+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 81.5, + "water_total": 1931.0, + "average_temperature": 28.9667, + "experience_temperature": 30.6381, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:40:07.360238+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 1953.0, + "average_temperature": 29.0667, + "experience_temperature": 31.3667, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T05:50:06.471216+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 80.7, + "water_total": 1980.0, + "average_temperature": 29.4, + "experience_temperature": 30.9114, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:00:07.265513+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 2006.0, + "average_temperature": 29.3, + "experience_temperature": 31.8, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:10:05.994571+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 2035.0, + "average_temperature": 28.7, + "experience_temperature": 30.8, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:20:07.302141+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 81.2, + "water_total": 2070.0, + "average_temperature": 28.9, + "experience_temperature": 31.14, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:30:06.636932+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 86.1, + "water_total": 2085.0, + "average_temperature": 28.7667, + "experience_temperature": 30.7295, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:40:07.051248+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.6, + "water_total": 2119.0, + "average_temperature": 28.3333, + "experience_temperature": 31.2533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T06:50:07.987921+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 81.6, + "water_total": 2145.0, + "average_temperature": 28.8333, + "experience_temperature": 30.5248, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:00:06.963307+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 2171.0, + "average_temperature": 29.6, + "experience_temperature": 31.9, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:10:06.424732+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 2200.0, + "average_temperature": 28.8333, + "experience_temperature": 31.4733, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:20:06.946015+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 2235.0, + "average_temperature": 28.9667, + "experience_temperature": 31.9667, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:30:06.435810+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 2270.0, + "average_temperature": 29.2, + "experience_temperature": 31.96, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:40:06.111866+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 2305.0, + "average_temperature": 29.3667, + "experience_temperature": 31.8467, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T07:50:05.995625+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 81.6, + "water_total": 2343.0, + "average_temperature": 29.9, + "experience_temperature": 32.22, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:00:05.981712+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 80.6, + "water_total": 2381.0, + "average_temperature": 30.1333, + "experience_temperature": 32.2533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:10:06.855375+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 80.1, + "water_total": 2422.0, + "average_temperature": 30.3667, + "experience_temperature": 31.7581, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:20:05.657935+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 80.0, + "water_total": 2450.0, + "average_temperature": 30.7333, + "experience_temperature": 32.7333, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:30:07.534751+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 75.8, + "water_total": 2503.0, + "average_temperature": 31.3, + "experience_temperature": 31.8314, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:40:05.889826+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 76.2, + "water_total": 2518.0, + "average_temperature": 31.6333, + "experience_temperature": 32.2448, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T08:50:06.701485+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 75.1, + "water_total": 2518.0, + "average_temperature": 31.6, + "experience_temperature": 31.3629, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:00:07.196616+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 73.4, + "water_total": 2518.0, + "average_temperature": 31.6333, + "experience_temperature": 30.4276, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:10:06.558381+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 73.6, + "water_total": 2518.0, + "average_temperature": 31.6, + "experience_temperature": 30.4343, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:20:06.269659+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.6, + "humidity": 73.2, + "water_total": 2518.0, + "average_temperature": 31.7667, + "experience_temperature": 28.6352, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:30:05.906790+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.6, + "humidity": 71.1, + "water_total": 2518.0, + "average_temperature": 31.9, + "experience_temperature": 28.3486, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:40:10.747134+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.5, + "humidity": 71.7, + "water_total": 2518.0, + "average_temperature": 32.1667, + "experience_temperature": 29.3638, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T09:50:05.196569+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.6, + "humidity": 70.1, + "water_total": 2518.0, + "average_temperature": 32.3333, + "experience_temperature": 28.5819, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:00:09.826659+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.0, + "humidity": 70.4, + "water_total": 2518.0, + "average_temperature": 32.6667, + "experience_temperature": 26.461, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:10:06.173084+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.8, + "humidity": 70.1, + "water_total": 2683.0, + "average_temperature": 32.3, + "experience_temperature": 27.2914, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:20:05.747822+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.8, + "humidity": 70.1, + "water_total": 2683.0, + "average_temperature": 32.3, + "experience_temperature": 27.2914, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:30:06.076170+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.6, + "humidity": 68.9, + "water_total": 2833.0, + "average_temperature": 32.6333, + "experience_temperature": 28.6419, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:40:05.948232+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.0, + "humidity": 67.3, + "water_total": 2863.0, + "average_temperature": 32.8333, + "experience_temperature": 26.0076, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T10:50:06.661941+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.3, + "humidity": 68.5, + "water_total": 2902.0, + "average_temperature": 33.2667, + "experience_temperature": 24.7952, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:00:07.644783+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.1, + "humidity": 68.8, + "water_total": 2928.0, + "average_temperature": 33.3333, + "experience_temperature": 26.179, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:10:07.274133+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.0, + "humidity": 67.7, + "water_total": 2929.0, + "average_temperature": 33.4333, + "experience_temperature": 26.6876, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:20:06.488504+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 66.4, + "water_total": 2929.0, + "average_temperature": 33.4333, + "experience_temperature": 25.1705, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:30:07.694493+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.1, + "humidity": 66.0, + "water_total": 2929.0, + "average_temperature": 33.6333, + "experience_temperature": 25.919, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:40:06.847956+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 63.7, + "water_total": 2929.0, + "average_temperature": 33.9333, + "experience_temperature": 25.1305, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T11:50:08.087786+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 63.7, + "water_total": 2929.0, + "average_temperature": 33.9333, + "experience_temperature": 25.1305, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:00:06.488523+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.1, + "humidity": 64.5, + "water_total": 2929.0, + "average_temperature": 33.9333, + "experience_temperature": 25.919, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:10:07.216816+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.3, + "humidity": 64.8, + "water_total": 2929.0, + "average_temperature": 33.7, + "experience_temperature": 24.4886, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:20:06.680184+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 63.2, + "water_total": 2929.0, + "average_temperature": 33.9, + "experience_temperature": 24.9971, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:30:06.053859+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.3, + "humidity": 63.1, + "water_total": 2929.0, + "average_temperature": 33.9333, + "experience_temperature": 24.3819, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:40:05.684318+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 63.4, + "water_total": 2929.0, + "average_temperature": 33.7667, + "experience_temperature": 24.9038, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T12:50:06.999432+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 63.7, + "water_total": 2929.0, + "average_temperature": 33.9333, + "experience_temperature": 25.1305, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:00:07.394997+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 61.7, + "water_total": 2960.0, + "average_temperature": 33.7333, + "experience_temperature": 24.5305, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:10:06.579752+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.9, + "humidity": 62.3, + "water_total": 2985.0, + "average_temperature": 34.0667, + "experience_temperature": 20.5838, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:20:06.155292+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.6, + "humidity": 62.5, + "water_total": 3010.0, + "average_temperature": 34.0667, + "experience_temperature": 22.5095, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:30:06.226331+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.6, + "humidity": 62.5, + "water_total": 3010.0, + "average_temperature": 34.0667, + "experience_temperature": 22.5095, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:40:06.560892+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.7, + "humidity": 62.4, + "water_total": 3071.0, + "average_temperature": 34.0667, + "experience_temperature": 21.861, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T13:50:06.313880+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.7, + "humidity": 62.4, + "water_total": 3071.0, + "average_temperature": 34.0667, + "experience_temperature": 21.861, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T14:10:06.359879+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.8, + "humidity": 60.6, + "water_total": 3152.0, + "average_temperature": 34.0667, + "experience_temperature": 20.8724, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T14:20:06.639634+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.8, + "humidity": 59.5, + "water_total": 3179.0, + "average_temperature": 34.0333, + "experience_temperature": 20.619, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T14:30:06.921284+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.1, + "humidity": 62.0, + "water_total": 3206.0, + "average_temperature": 33.9333, + "experience_temperature": 25.419, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T14:40:16.975591+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.1, + "humidity": 62.0, + "water_total": 3206.0, + "average_temperature": 33.9333, + "experience_temperature": 25.419, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T14:50:07.594450+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 69.7, + "water_total": 3267.0, + "average_temperature": 33.4, + "experience_temperature": 25.7971, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T15:10:07.935632+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 71.2, + "water_total": 3309.0, + "average_temperature": 32.8667, + "experience_temperature": 25.5638, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T15:20:10.252738+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.2, + "humidity": 71.1, + "water_total": 3327.0, + "average_temperature": 32.8667, + "experience_temperature": 25.5438, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T15:30:06.129373+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 1.4, + "humidity": 70.4, + "water_total": 3352.0, + "average_temperature": 32.5667, + "experience_temperature": 23.8467, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T15:40:08.355293+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.8, + "humidity": 70.9, + "water_total": 3379.0, + "average_temperature": 32.4333, + "experience_temperature": 27.5848, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T15:50:06.919639+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.7, + "humidity": 72.0, + "water_total": 3403.0, + "average_temperature": 32.3, + "experience_temperature": 28.3, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T16:10:06.790800+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.6, + "humidity": 71.6, + "water_total": 3458.0, + "average_temperature": 32.0667, + "experience_temperature": 28.6152, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T16:20:06.838194+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.7, + "humidity": 71.7, + "water_total": 3482.0, + "average_temperature": 31.8333, + "experience_temperature": 27.7733, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T16:30:08.538320+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.7, + "humidity": 72.6, + "water_total": 3506.0, + "average_temperature": 31.7, + "experience_temperature": 27.82, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T16:40:07.747111+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.7, + "humidity": 72.4, + "water_total": 3529.0, + "average_temperature": 31.6, + "experience_temperature": 27.68, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T16:50:06.844227+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 72.8, + "water_total": 3553.0, + "average_temperature": 31.5333, + "experience_temperature": 31.4648, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T17:10:05.661725+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.4, + "humidity": 71.8, + "water_total": 32.0, + "average_temperature": 31.4333, + "experience_temperature": 29.279, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T17:20:06.846143+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 73.7, + "water_total": 56.0, + "average_temperature": 31.3, + "experience_temperature": 30.1543, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T17:30:07.990159+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 74.2, + "water_total": 86.0, + "average_temperature": 31.2333, + "experience_temperature": 30.8162, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T17:40:07.205217+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 74.2, + "water_total": 86.0, + "average_temperature": 31.2333, + "experience_temperature": 30.8162, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T17:50:06.358739+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 74.7, + "water_total": 146.0, + "average_temperature": 31.0, + "experience_temperature": 30.6829, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:00:05.790138+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 74.7, + "water_total": 146.0, + "average_temperature": 31.0, + "experience_temperature": 30.6829, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:10:06.224628+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.4, + "humidity": 76.7, + "water_total": 201.0, + "average_temperature": 30.7, + "experience_temperature": 29.5257, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:20:05.891954+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 77.8, + "water_total": 230.0, + "average_temperature": 30.4667, + "experience_temperature": 30.141, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:30:06.574715+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 254.0, + "average_temperature": 30.2333, + "experience_temperature": 30.3562, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:40:09.975637+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 284.0, + "average_temperature": 30.4333, + "experience_temperature": 30.5562, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T18:50:06.477815+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 78.4, + "water_total": 324.0, + "average_temperature": 30.6333, + "experience_temperature": 31.0562, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:00:05.812335+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 78.8, + "water_total": 348.0, + "average_temperature": 30.4333, + "experience_temperature": 31.5648, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:10:07.374446+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 78.8, + "water_total": 385.0, + "average_temperature": 30.4667, + "experience_temperature": 30.9695, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:20:05.679190+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 79.3, + "water_total": 422.0, + "average_temperature": 30.4, + "experience_temperature": 31.0029, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:30:06.160693+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 78.8, + "water_total": 448.0, + "average_temperature": 30.3, + "experience_temperature": 30.8029, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:40:07.862971+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 78.0, + "water_total": 477.0, + "average_temperature": 30.2, + "experience_temperature": 30.5429, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T19:50:05.935193+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 79.3, + "water_total": 507.0, + "average_temperature": 30.3667, + "experience_temperature": 32.2267, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:00:06.864832+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 80.1, + "water_total": 538.0, + "average_temperature": 30.3, + "experience_temperature": 31.0629, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:10:06.352141+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 80.3, + "water_total": 562.0, + "average_temperature": 30.3, + "experience_temperature": 31.1029, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:20:06.173572+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 590.0, + "average_temperature": 30.3, + "experience_temperature": 31.1829, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:30:06.020724+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 82.2, + "water_total": 619.0, + "average_temperature": 30.3667, + "experience_temperature": 31.5495, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:40:06.971695+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 80.7, + "water_total": 647.0, + "average_temperature": 30.3, + "experience_temperature": 30.5543, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T20:50:07.314087+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 670.0, + "average_temperature": 30.3667, + "experience_temperature": 31.2095, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:00:06.808027+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 692.0, + "average_temperature": 30.2667, + "experience_temperature": 31.1695, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:10:06.377828+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 81.9, + "water_total": 719.0, + "average_temperature": 30.2333, + "experience_temperature": 30.7276, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:20:07.355193+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 80.9, + "water_total": 735.0, + "average_temperature": 30.1333, + "experience_temperature": 30.4276, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:30:07.275781+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 81.6, + "water_total": 756.0, + "average_temperature": 30.2, + "experience_temperature": 31.2629, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:40:05.434275+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 82.0, + "water_total": 772.0, + "average_temperature": 30.0333, + "experience_temperature": 30.5476, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T21:50:07.110876+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 83.1, + "water_total": 787.0, + "average_temperature": 29.9333, + "experience_temperature": 31.9248, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:00:06.184900+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 82.3, + "water_total": 803.0, + "average_temperature": 29.7, + "experience_temperature": 30.9029, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:10:05.787311+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 83.6, + "water_total": 818.0, + "average_temperature": 29.8333, + "experience_temperature": 31.9248, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:20:06.365791+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 833.0, + "average_temperature": 29.7333, + "experience_temperature": 31.0362, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:30:08.559954+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 83.4, + "water_total": 849.0, + "average_temperature": 29.8333, + "experience_temperature": 32.5133, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:40:08.534144+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 82.9, + "water_total": 864.0, + "average_temperature": 29.7333, + "experience_temperature": 31.6848, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T22:50:06.617746+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 879.0, + "average_temperature": 29.8333, + "experience_temperature": 32.6533, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:00:06.359971+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 83.8, + "water_total": 884.0, + "average_temperature": 29.6333, + "experience_temperature": 31.1362, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:10:06.296501+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 83.8, + "water_total": 889.0, + "average_temperature": 29.6667, + "experience_temperature": 31.1695, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:20:07.380894+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.1, + "humidity": 83.2, + "water_total": 893.0, + "average_temperature": 29.3667, + "experience_temperature": 31.3781, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:30:06.779185+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 84.3, + "water_total": 893.0, + "average_temperature": 29.5, + "experience_temperature": 31.1029, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:40:07.123652+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.2, + "humidity": 83.9, + "water_total": 898.0, + "average_temperature": 29.3667, + "experience_temperature": 30.8895, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-02T23:50:07.515702+07:00", + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 82.9, + "water_total": 903.0, + "average_temperature": 29.4, + "experience_temperature": 30.0943, + "chill_factor": 6.2857 + }, + { + "timestamp": "2026-06-03T00:00:06.074429+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.3, + "water_total": 903.0, + "average_temperature": 29.3, + "experience_temperature": 31.3457, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T00:10:06.606409+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 84.3, + "water_total": 923.0, + "average_temperature": 29.7, + "experience_temperature": 31.3314, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T00:20:06.225818+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.0, + "water_total": 981.0, + "average_temperature": 29.7, + "experience_temperature": 31.6857, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T00:30:06.549530+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 1020.0, + "average_temperature": 29.1333, + "experience_temperature": 31.8533, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T00:40:07.454504+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 1035.0, + "average_temperature": 28.6667, + "experience_temperature": 31.4667, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T00:50:07.183231+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 1045.0, + "average_temperature": 28.6, + "experience_temperature": 31.24, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:00:06.609716+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.3, + "water_total": 1061.0, + "average_temperature": 29.1333, + "experience_temperature": 31.3933, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:10:05.711075+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 82.4, + "water_total": 1076.0, + "average_temperature": 28.7667, + "experience_temperature": 31.2467, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:20:07.081466+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 82.7, + "water_total": 1086.0, + "average_temperature": 28.7333, + "experience_temperature": 31.2733, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:30:07.309697+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.7, + "water_total": 1101.0, + "average_temperature": 28.7333, + "experience_temperature": 30.859, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:40:06.062505+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 1141.0, + "average_temperature": 29.1, + "experience_temperature": 31.48, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T01:50:05.458701+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 1156.0, + "average_temperature": 28.4667, + "experience_temperature": 31.0867, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:00:05.913432+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 1166.0, + "average_temperature": 28.7, + "experience_temperature": 30.92, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:10:06.956811+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 1180.0, + "average_temperature": 29.6, + "experience_temperature": 31.94, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:20:06.122417+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.1, + "water_total": 1190.0, + "average_temperature": 28.6667, + "experience_temperature": 30.4724, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:30:06.318821+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 1211.0, + "average_temperature": 28.7667, + "experience_temperature": 29.8381, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:40:06.731329+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 79.2, + "water_total": 1221.0, + "average_temperature": 29.6333, + "experience_temperature": 30.2448, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T02:50:06.916584+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 1243.0, + "average_temperature": 29.0333, + "experience_temperature": 31.5933, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:00:06.705386+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.7, + "water_total": 1271.0, + "average_temperature": 28.4333, + "experience_temperature": 30.7733, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:10:05.958666+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.3, + "water_total": 1287.0, + "average_temperature": 28.9333, + "experience_temperature": 29.7648, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:20:05.914150+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 79.1, + "water_total": 1308.0, + "average_temperature": 29.4667, + "experience_temperature": 29.4438, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:30:05.971957+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 79.1, + "water_total": 1308.0, + "average_temperature": 29.4667, + "experience_temperature": 29.4438, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:40:05.765354+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 1333.0, + "average_temperature": 28.3667, + "experience_temperature": 29.4381, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T03:50:05.838786+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 1355.0, + "average_temperature": 28.7667, + "experience_temperature": 30.9667, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:00:07.055883+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 1359.0, + "average_temperature": 29.2333, + "experience_temperature": 30.1048, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:10:07.305154+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 1364.0, + "average_temperature": 29.4667, + "experience_temperature": 32.1067, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:20:06.184507+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 1364.0, + "average_temperature": 29.4667, + "experience_temperature": 32.1067, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:30:06.652930+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.2, + "water_total": 1384.0, + "average_temperature": 28.8333, + "experience_temperature": 30.659, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:40:07.104445+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.3, + "water_total": 1420.0, + "average_temperature": 28.4667, + "experience_temperature": 30.3124, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T04:50:06.160867+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.2, + "water_total": 1436.0, + "average_temperature": 28.7667, + "experience_temperature": 29.5781, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:00:06.213148+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 79.2, + "water_total": 1452.0, + "average_temperature": 29.5333, + "experience_temperature": 30.1448, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:10:07.021506+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 1473.0, + "average_temperature": 29.0, + "experience_temperature": 31.94, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:20:07.128638+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 80.7, + "water_total": 1501.0, + "average_temperature": 28.1333, + "experience_temperature": 29.659, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:30:07.028799+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 81.0, + "water_total": 1527.0, + "average_temperature": 28.5667, + "experience_temperature": 30.1524, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:40:06.105718+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 79.9, + "water_total": 1539.0, + "average_temperature": 29.2, + "experience_temperature": 30.5657, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T05:50:06.434158+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 1576.0, + "average_temperature": 29.7333, + "experience_temperature": 32.1133, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:00:06.322241+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 80.2, + "water_total": 1608.0, + "average_temperature": 28.3667, + "experience_temperature": 29.7924, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:10:06.383099+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 79.4, + "water_total": 1625.0, + "average_temperature": 28.9667, + "experience_temperature": 30.2324, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:20:06.847085+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 1669.0, + "average_temperature": 29.6333, + "experience_temperature": 30.6448, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:30:06.596018+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 82.6, + "water_total": 1709.0, + "average_temperature": 29.3667, + "experience_temperature": 31.8867, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:40:07.196617+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 1763.0, + "average_temperature": 28.6667, + "experience_temperature": 30.4324, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T06:50:06.624311+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 1807.0, + "average_temperature": 29.4333, + "experience_temperature": 30.3648, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:00:06.761256+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.8, + "water_total": 1855.0, + "average_temperature": 28.7, + "experience_temperature": 31.46, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:10:06.481138+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 82.4, + "water_total": 1907.0, + "average_temperature": 29.0333, + "experience_temperature": 29.6705, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:20:06.361410+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 1958.0, + "average_temperature": 28.9333, + "experience_temperature": 30.2648, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:30:06.698060+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.7, + "water_total": 2006.0, + "average_temperature": 29.0667, + "experience_temperature": 31.1924, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:40:06.304538+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.9, + "water_total": 2054.0, + "average_temperature": 28.7, + "experience_temperature": 30.2514, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T07:50:06.141077+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.8, + "water_total": 2099.0, + "average_temperature": 29.1333, + "experience_temperature": 31.079, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:00:07.371972+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.8, + "water_total": 2155.0, + "average_temperature": 29.4667, + "experience_temperature": 31.4124, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:10:06.691308+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.8, + "water_total": 2155.0, + "average_temperature": 29.4667, + "experience_temperature": 31.4124, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:20:06.295197+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 81.0, + "water_total": 2255.0, + "average_temperature": 30.3, + "experience_temperature": 31.8857, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:30:07.472755+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 2298.0, + "average_temperature": 30.6333, + "experience_temperature": 32.6848, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:40:07.068979+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 79.9, + "water_total": 2366.0, + "average_temperature": 31.2, + "experience_temperature": 31.9514, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T08:50:06.273943+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.6, + "humidity": 76.7, + "water_total": 2417.0, + "average_temperature": 31.4333, + "experience_temperature": 29.0876, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:00:07.196463+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.6, + "humidity": 76.7, + "water_total": 2468.0, + "average_temperature": 31.4333, + "experience_temperature": 29.0876, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:10:06.862992+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 76.1, + "water_total": 2511.0, + "average_temperature": 31.6333, + "experience_temperature": 27.939, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:20:06.631337+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.9, + "humidity": 75.3, + "water_total": 2566.0, + "average_temperature": 31.8667, + "experience_temperature": 27.3981, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:30:09.798424+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 74.0, + "water_total": 2614.0, + "average_temperature": 31.7333, + "experience_temperature": 27.619, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:40:07.374040+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.7, + "humidity": 75.0, + "water_total": 2665.0, + "average_temperature": 32.0333, + "experience_temperature": 28.7333, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T09:50:06.685699+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 74.8, + "water_total": 2721.0, + "average_temperature": 32.0333, + "experience_temperature": 28.079, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:00:08.147564+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 74.3, + "water_total": 2776.0, + "average_temperature": 32.3667, + "experience_temperature": 28.3124, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:10:08.728955+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 73.5, + "water_total": 2821.0, + "average_temperature": 32.4333, + "experience_temperature": 25.7619, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:20:07.834867+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 73.3, + "water_total": 2863.0, + "average_temperature": 32.5667, + "experience_temperature": 25.8552, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:30:07.808751+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 73.1, + "water_total": 2908.0, + "average_temperature": 32.4, + "experience_temperature": 28.1057, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:40:07.047030+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 70.7, + "water_total": 2964.0, + "average_temperature": 32.6333, + "experience_temperature": 24.7876, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T10:50:08.018691+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 69.8, + "water_total": 3012.0, + "average_temperature": 32.8333, + "experience_temperature": 25.4219, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:00:09.366119+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 67.5, + "water_total": 3052.0, + "average_temperature": 33.3, + "experience_temperature": 24.8143, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:10:08.050055+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 69.1, + "water_total": 3119.0, + "average_temperature": 33.3667, + "experience_temperature": 25.8152, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:20:07.902412+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.1, + "humidity": 68.5, + "water_total": 3159.0, + "average_temperature": 33.3667, + "experience_temperature": 26.3095, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:30:06.645943+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 65.9, + "water_total": 3209.0, + "average_temperature": 33.3, + "experience_temperature": 25.1086, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:40:09.220665+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 66.0, + "water_total": 3257.0, + "average_temperature": 33.6667, + "experience_temperature": 25.4952, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T11:50:07.157774+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 65.6, + "water_total": 3312.0, + "average_temperature": 33.8, + "experience_temperature": 25.5486, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:00:08.695686+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.4, + "humidity": 62.9, + "water_total": 3366.0, + "average_temperature": 33.7333, + "experience_temperature": 23.7133, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:10:08.005240+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.5, + "humidity": 65.0, + "water_total": 3418.0, + "average_temperature": 33.8667, + "experience_temperature": 23.6524, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:20:06.615159+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 64.4, + "water_total": 3457.0, + "average_temperature": 33.7333, + "experience_temperature": 25.2419, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:30:07.728293+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 65.7, + "water_total": 3497.0, + "average_temperature": 33.7667, + "experience_temperature": 24.921, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:40:07.029523+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.5, + "humidity": 64.1, + "water_total": 3503.0, + "average_temperature": 33.4333, + "experience_temperature": 23.039, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T12:50:07.186341+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 64.0, + "water_total": 3503.0, + "average_temperature": 33.3667, + "experience_temperature": 24.181, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:00:08.402440+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.7, + "humidity": 67.1, + "water_total": 3503.0, + "average_temperature": 33.8667, + "experience_temperature": 22.8438, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:10:08.599008+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 66.3, + "water_total": 3503.0, + "average_temperature": 33.7, + "experience_temperature": 25.5886, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:20:07.965215+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 66.3, + "water_total": 3503.0, + "average_temperature": 33.7, + "experience_temperature": 25.5886, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:30:09.343413+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.8, + "humidity": 66.2, + "water_total": 3503.0, + "average_temperature": 33.8667, + "experience_temperature": 22.0495, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:40:07.349931+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.8, + "humidity": 66.2, + "water_total": 3503.0, + "average_temperature": 33.8667, + "experience_temperature": 22.0495, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T13:50:07.973753+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 63.9, + "water_total": 3555.0, + "average_temperature": 33.8, + "experience_temperature": 24.5943, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T14:10:07.702224+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 62.1, + "water_total": 3749.0, + "average_temperature": 33.6, + "experience_temperature": 24.6486, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T14:20:07.174222+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.8, + "humidity": 65.2, + "water_total": 3803.0, + "average_temperature": 33.8667, + "experience_temperature": 21.8495, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T14:30:06.765310+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 67.2, + "water_total": 3851.0, + "average_temperature": 33.6667, + "experience_temperature": 25.121, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T14:40:07.698953+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.3, + "humidity": 66.6, + "water_total": 3913.0, + "average_temperature": 33.7333, + "experience_temperature": 25.0676, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T14:50:09.089109+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 67.8, + "water_total": 3949.0, + "average_temperature": 33.7333, + "experience_temperature": 25.9219, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T15:10:07.301983+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.6, + "humidity": 71.6, + "water_total": 4024.0, + "average_temperature": 32.3, + "experience_temperature": 28.9343, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T15:20:07.694381+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.0, + "humidity": 72.0, + "water_total": 4044.0, + "average_temperature": 32.3333, + "experience_temperature": 26.5905, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T15:30:06.928108+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 71.9, + "water_total": 4090.0, + "average_temperature": 32.4, + "experience_temperature": 25.4086, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T15:40:07.614927+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 71.3, + "water_total": 4124.0, + "average_temperature": 32.3667, + "experience_temperature": 25.2552, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T15:50:06.787842+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 1.2, + "humidity": 71.7, + "water_total": 4171.0, + "average_temperature": 32.2667, + "experience_temperature": 25.2352, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T16:10:07.675230+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 73.4, + "water_total": 4242.0, + "average_temperature": 32.2333, + "experience_temperature": 27.999, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T16:20:07.290970+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 73.3, + "water_total": 4296.0, + "average_temperature": 32.2, + "experience_temperature": 27.9457, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T16:30:07.439139+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 73.3, + "water_total": 4296.0, + "average_temperature": 32.2, + "experience_temperature": 27.9457, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T16:40:07.755840+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.6, + "humidity": 73.5, + "water_total": 4386.0, + "average_temperature": 31.6667, + "experience_temperature": 28.681, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T16:50:07.444587+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 74.3, + "water_total": 4423.0, + "average_temperature": 31.6333, + "experience_temperature": 27.579, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T17:10:08.146929+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.6, + "humidity": 74.7, + "water_total": 30.0, + "average_temperature": 31.3667, + "experience_temperature": 28.621, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T17:20:07.084248+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.8, + "humidity": 75.6, + "water_total": 77.0, + "average_temperature": 31.4667, + "experience_temperature": 27.6724, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T17:30:05.701093+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.7, + "humidity": 75.1, + "water_total": 120.0, + "average_temperature": 31.4333, + "experience_temperature": 28.1533, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T17:40:05.655029+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 75.2, + "water_total": 161.0, + "average_temperature": 31.2, + "experience_temperature": 31.0114, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T17:50:05.788283+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 75.9, + "water_total": 207.0, + "average_temperature": 31.2667, + "experience_temperature": 31.2181, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:00:05.436136+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 76.2, + "water_total": 249.0, + "average_temperature": 31.2667, + "experience_temperature": 31.2781, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:10:06.347333+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 77.2, + "water_total": 294.0, + "average_temperature": 31.2667, + "experience_temperature": 32.0924, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:20:06.962062+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 78.2, + "water_total": 337.0, + "average_temperature": 31.2, + "experience_temperature": 32.2257, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:30:05.981907+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 78.0, + "water_total": 387.0, + "average_temperature": 31.0333, + "experience_temperature": 30.7905, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:40:05.727349+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 77.1, + "water_total": 424.0, + "average_temperature": 30.8667, + "experience_temperature": 31.6724, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T18:50:06.195844+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 77.1, + "water_total": 462.0, + "average_temperature": 30.8333, + "experience_temperature": 31.0248, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:00:06.013082+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 78.6, + "water_total": 509.0, + "average_temperature": 30.9667, + "experience_temperature": 31.4581, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:10:05.501772+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 77.8, + "water_total": 559.0, + "average_temperature": 30.7667, + "experience_temperature": 31.7124, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:20:07.456425+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.3, + "water_total": 599.0, + "average_temperature": 30.8, + "experience_temperature": 31.8314, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:30:06.170761+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 80.2, + "water_total": 644.0, + "average_temperature": 30.6, + "experience_temperature": 30.7971, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:40:06.517459+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 688.0, + "average_temperature": 30.6333, + "experience_temperature": 31.5448, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T19:50:06.008094+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.3, + "water_total": 733.0, + "average_temperature": 30.4333, + "experience_temperature": 31.4648, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:00:05.784301+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 774.0, + "average_temperature": 30.3333, + "experience_temperature": 31.2448, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:10:05.489814+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 805.0, + "average_temperature": 30.2, + "experience_temperature": 31.2114, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:20:06.064655+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.0, + "water_total": 844.0, + "average_temperature": 30.2333, + "experience_temperature": 31.2048, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:30:06.126307+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 80.9, + "water_total": 893.0, + "average_temperature": 30.5, + "experience_temperature": 30.8371, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:40:08.903640+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 82.0, + "water_total": 934.0, + "average_temperature": 30.2333, + "experience_temperature": 31.4048, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T20:50:06.515603+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.4, + "water_total": 981.0, + "average_temperature": 30.3333, + "experience_temperature": 31.3848, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:00:06.045700+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 1017.0, + "average_temperature": 30.3333, + "experience_temperature": 31.4048, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:10:05.929319+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 1058.0, + "average_temperature": 30.2333, + "experience_temperature": 31.5048, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:20:05.978066+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 82.2, + "water_total": 1096.0, + "average_temperature": 30.2, + "experience_temperature": 31.4114, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:30:06.112797+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 82.7, + "water_total": 1138.0, + "average_temperature": 30.0333, + "experience_temperature": 31.959, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:40:06.641163+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.3, + "water_total": 1169.0, + "average_temperature": 29.9333, + "experience_temperature": 31.979, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T21:50:06.468207+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.3, + "humidity": 84.2, + "water_total": 1209.0, + "average_temperature": 30.0, + "experience_temperature": 30.9971, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:00:07.354527+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.0, + "humidity": 83.9, + "water_total": 1244.0, + "average_temperature": 29.9667, + "experience_temperature": 32.7467, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:10:06.249908+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.7, + "water_total": 1280.0, + "average_temperature": 29.9667, + "experience_temperature": 31.4781, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:20:06.087337+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.2, + "water_total": 1313.0, + "average_temperature": 29.8667, + "experience_temperature": 31.2781, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:30:05.892737+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.5, + "water_total": 1339.0, + "average_temperature": 29.9, + "experience_temperature": 31.9857, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:40:06.502561+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.4, + "water_total": 1380.0, + "average_temperature": 30.2333, + "experience_temperature": 31.6848, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T22:50:05.585143+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.5, + "water_total": 1416.0, + "average_temperature": 30.3, + "experience_temperature": 32.3857, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:00:06.020484+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.1, + "water_total": 1444.0, + "average_temperature": 29.9333, + "experience_temperature": 31.3248, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:10:06.016480+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.1, + "humidity": 83.6, + "water_total": 1475.0, + "average_temperature": 29.9667, + "experience_temperature": 32.0724, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:20:06.800396+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 84.2, + "water_total": 1502.0, + "average_temperature": 30.0, + "experience_temperature": 31.6114, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:30:06.871334+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 84.2, + "water_total": 1531.0, + "average_temperature": 29.9667, + "experience_temperature": 31.5781, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:40:06.827065+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 84.0, + "water_total": 1566.0, + "average_temperature": 30.0667, + "experience_temperature": 31.6381, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-03T23:50:06.008440+07:00", + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.1, + "water_total": 1583.0, + "average_temperature": 29.8333, + "experience_temperature": 31.2248, + "chill_factor": 6.1429 + }, + { + "timestamp": "2026-06-04T00:00:05.739499+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 83.1, + "water_total": 1583.0, + "average_temperature": 29.8333, + "experience_temperature": 31.2533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T00:10:08.351484+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.8, + "water_total": 1621.0, + "average_temperature": 29.6667, + "experience_temperature": 32.0267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T00:20:06.676424+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 83.9, + "water_total": 1672.0, + "average_temperature": 29.6333, + "experience_temperature": 31.2133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T00:30:06.924278+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 84.0, + "water_total": 1697.0, + "average_temperature": 29.3333, + "experience_temperature": 30.3333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T00:40:06.021646+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.5, + "water_total": 1726.0, + "average_temperature": 29.2667, + "experience_temperature": 30.9667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T00:50:06.677787+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.4, + "water_total": 1750.0, + "average_temperature": 29.3667, + "experience_temperature": 31.8467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:00:06.322582+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.8, + "water_total": 1784.0, + "average_temperature": 29.2, + "experience_temperature": 31.56, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:10:07.129443+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.1, + "water_total": 1809.0, + "average_temperature": 29.2, + "experience_temperature": 31.62, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:20:08.281110+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.9, + "water_total": 1838.0, + "average_temperature": 29.1667, + "experience_temperature": 31.5467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:30:05.796464+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 84.8, + "water_total": 1868.0, + "average_temperature": 29.1667, + "experience_temperature": 32.1267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:40:05.687891+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 85.1, + "water_total": 1902.0, + "average_temperature": 29.4333, + "experience_temperature": 32.4533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T01:50:06.587110+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 84.5, + "water_total": 1948.0, + "average_temperature": 29.2667, + "experience_temperature": 32.1667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:00:06.108345+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.0, + "water_total": 1981.0, + "average_temperature": 28.8667, + "experience_temperature": 31.2667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:10:05.888151+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.2, + "water_total": 1998.0, + "average_temperature": 28.6333, + "experience_temperature": 31.0733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:20:06.719883+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.2, + "water_total": 1998.0, + "average_temperature": 28.6333, + "experience_temperature": 31.0733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:30:05.991436+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.1, + "water_total": 2050.0, + "average_temperature": 28.6667, + "experience_temperature": 30.4867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:40:05.728778+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.1, + "water_total": 2050.0, + "average_temperature": 28.6667, + "experience_temperature": 30.4867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T02:50:06.366791+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.1, + "water_total": 2103.0, + "average_temperature": 28.6, + "experience_temperature": 30.42, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:00:05.295906+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.0, + "water_total": 2125.0, + "average_temperature": 28.5, + "experience_temperature": 30.3, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:10:06.126210+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.6, + "water_total": 2146.0, + "average_temperature": 28.4333, + "experience_temperature": 30.9533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:20:06.868020+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 2162.0, + "average_temperature": 29.5, + "experience_temperature": 32.5, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:30:07.439759+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.9, + "water_total": 2178.0, + "average_temperature": 28.4667, + "experience_temperature": 30.8467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:40:06.944645+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 87.2, + "water_total": 2200.0, + "average_temperature": 28.9667, + "experience_temperature": 32.4067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T03:50:06.103037+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.4, + "water_total": 2216.0, + "average_temperature": 28.3667, + "experience_temperature": 30.0467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:00:05.918312+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 83.3, + "water_total": 2227.0, + "average_temperature": 29.3667, + "experience_temperature": 30.8267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:10:05.889048+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.3, + "water_total": 2260.0, + "average_temperature": 28.7, + "experience_temperature": 30.56, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:20:06.088007+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.7, + "water_total": 2316.0, + "average_temperature": 29.0667, + "experience_temperature": 31.0067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:30:05.745728+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.9, + "water_total": 2357.0, + "average_temperature": 28.3667, + "experience_temperature": 30.7467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:40:06.129688+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 84.0, + "water_total": 2374.0, + "average_temperature": 29.2667, + "experience_temperature": 30.2667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T04:50:06.162020+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.1, + "water_total": 2416.0, + "average_temperature": 28.3, + "experience_temperature": 30.72, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:00:05.784787+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.3, + "water_total": 2452.0, + "average_temperature": 28.9667, + "experience_temperature": 31.2267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:10:06.301804+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.7, + "water_total": 2485.0, + "average_temperature": 28.4, + "experience_temperature": 30.94, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:20:06.514702+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 85.1, + "water_total": 2515.0, + "average_temperature": 29.7333, + "experience_temperature": 30.9533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:30:06.789659+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 83.0, + "water_total": 2557.0, + "average_temperature": 29.1333, + "experience_temperature": 29.9333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:40:06.201055+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.6, + "water_total": 2579.0, + "average_temperature": 28.4333, + "experience_temperature": 30.9533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T05:50:06.257983+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 83.2, + "water_total": 2593.0, + "average_temperature": 28.6, + "experience_temperature": 30.64, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:00:05.515190+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 2609.0, + "average_temperature": 29.6, + "experience_temperature": 32.54, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:10:07.646188+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 83.7, + "water_total": 2632.0, + "average_temperature": 28.7, + "experience_temperature": 30.24, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:20:07.302847+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 84.9, + "water_total": 2660.0, + "average_temperature": 28.5, + "experience_temperature": 29.68, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:30:06.887159+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 85.4, + "water_total": 2669.0, + "average_temperature": 29.3667, + "experience_temperature": 32.4467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:40:06.643744+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.3, + "water_total": 2677.0, + "average_temperature": 28.6667, + "experience_temperature": 30.3267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T06:50:06.190793+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.7, + "water_total": 2677.0, + "average_temperature": 28.7667, + "experience_temperature": 30.5067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:00:07.620492+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.6, + "water_total": 2677.0, + "average_temperature": 28.9667, + "experience_temperature": 31.2867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:10:06.687196+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.5, + "water_total": 2677.0, + "average_temperature": 28.9333, + "experience_temperature": 31.2333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:20:07.012061+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.5, + "water_total": 2677.0, + "average_temperature": 29.0333, + "experience_temperature": 30.7333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:30:06.217264+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.5, + "water_total": 2677.0, + "average_temperature": 29.1333, + "experience_temperature": 31.4333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:40:06.292176+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 84.1, + "water_total": 2677.0, + "average_temperature": 29.3667, + "experience_temperature": 30.9867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T07:50:06.633345+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 84.3, + "water_total": 2677.0, + "average_temperature": 29.8, + "experience_temperature": 32.06, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:00:09.715514+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 84.1, + "water_total": 2677.0, + "average_temperature": 30.3333, + "experience_temperature": 33.1533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:10:06.921476+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 82.2, + "water_total": 2677.0, + "average_temperature": 30.7333, + "experience_temperature": 32.5733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:20:07.139314+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.6, + "humidity": 81.8, + "water_total": 2677.0, + "average_temperature": 31.2667, + "experience_temperature": 30.0267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:30:06.447467+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 2677.0, + "average_temperature": 31.1, + "experience_temperature": 32.0, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:40:06.779623+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 79.7, + "water_total": 2677.0, + "average_temperature": 31.2, + "experience_temperature": 32.54, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T08:50:06.443603+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 77.6, + "water_total": 2677.0, + "average_temperature": 31.3333, + "experience_temperature": 28.0533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:00:07.121707+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 76.9, + "water_total": 2677.0, + "average_temperature": 31.2667, + "experience_temperature": 27.8467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:10:08.212402+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 77.0, + "water_total": 2677.0, + "average_temperature": 31.5333, + "experience_temperature": 28.1333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:20:07.191356+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 76.4, + "water_total": 2677.0, + "average_temperature": 31.7333, + "experience_temperature": 28.2133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:30:07.597599+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.7, + "humidity": 75.8, + "water_total": 2677.0, + "average_temperature": 32.1, + "experience_temperature": 29.06, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:40:07.429361+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.7, + "humidity": 74.9, + "water_total": 2677.0, + "average_temperature": 32.0667, + "experience_temperature": 28.8467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T09:50:08.289172+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.9, + "humidity": 76.3, + "water_total": 2677.0, + "average_temperature": 32.2, + "experience_temperature": 28.06, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:00:08.582831+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 74.7, + "water_total": 2677.0, + "average_temperature": 32.1, + "experience_temperature": 28.24, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:10:08.217432+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 75.1, + "water_total": 2677.0, + "average_temperature": 31.8667, + "experience_temperature": 28.0867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:20:06.899559+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.0, + "humidity": 73.2, + "water_total": 2689.0, + "average_temperature": 32.4333, + "experience_temperature": 27.0733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:30:13.919298+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 72.5, + "water_total": 2717.0, + "average_temperature": 32.5, + "experience_temperature": 25.8, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:40:07.298812+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 71.7, + "water_total": 2741.0, + "average_temperature": 32.5, + "experience_temperature": 25.64, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T10:50:06.614865+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.3, + "humidity": 72.2, + "water_total": 2787.0, + "average_temperature": 33.0333, + "experience_temperature": 25.6733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:00:06.876628+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 71.2, + "water_total": 2829.0, + "average_temperature": 32.7333, + "experience_temperature": 25.7733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:10:07.589999+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.4, + "humidity": 72.7, + "water_total": 2859.0, + "average_temperature": 32.5333, + "experience_temperature": 24.6733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:20:07.166386+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.4, + "humidity": 73.2, + "water_total": 2886.0, + "average_temperature": 33.0, + "experience_temperature": 25.24, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:30:08.216415+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 70.1, + "water_total": 2930.0, + "average_temperature": 33.5667, + "experience_temperature": 26.3867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:40:10.603502+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 69.2, + "water_total": 2950.0, + "average_temperature": 33.4667, + "experience_temperature": 26.1067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T11:50:06.431568+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 70.1, + "water_total": 2950.0, + "average_temperature": 33.7, + "experience_temperature": 26.52, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:00:09.255999+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.8, + "humidity": 70.2, + "water_total": 2953.0, + "average_temperature": 33.6667, + "experience_temperature": 22.9067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:10:06.798769+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.2, + "humidity": 68.2, + "water_total": 2955.0, + "average_temperature": 33.4, + "experience_temperature": 25.84, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:20:07.605444+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.7, + "humidity": 69.7, + "water_total": 2968.0, + "average_temperature": 33.9333, + "experience_temperature": 23.6733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:30:07.168239+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.3, + "humidity": 68.8, + "water_total": 2979.0, + "average_temperature": 33.6333, + "experience_temperature": 25.5933, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:40:06.881961+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.6, + "humidity": 68.9, + "water_total": 2980.0, + "average_temperature": 33.8333, + "experience_temperature": 24.0133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T12:50:06.564585+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.7, + "humidity": 69.6, + "water_total": 2980.0, + "average_temperature": 33.7333, + "experience_temperature": 23.4533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:00:06.648417+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.7, + "humidity": 68.7, + "water_total": 2980.0, + "average_temperature": 33.7667, + "experience_temperature": 23.3067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:10:07.513965+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.7, + "humidity": 68.2, + "water_total": 2980.0, + "average_temperature": 34.0333, + "experience_temperature": 23.4733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:20:07.075562+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.8, + "humidity": 67.1, + "water_total": 2984.0, + "average_temperature": 33.8333, + "experience_temperature": 22.4533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:30:07.245053+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.4, + "humidity": 67.5, + "water_total": 2985.0, + "average_temperature": 33.6333, + "experience_temperature": 24.7333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:40:07.072813+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.6, + "humidity": 68.1, + "water_total": 2985.0, + "average_temperature": 33.7333, + "experience_temperature": 23.7533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T13:50:08.446080+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 1.8, + "humidity": 68.9, + "water_total": 2985.0, + "average_temperature": 33.6667, + "experience_temperature": 22.6467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T14:10:06.985382+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 73.8, + "water_total": 2985.0, + "average_temperature": 32.0, + "experience_temperature": 27.96, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T14:20:06.087590+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.8, + "humidity": 74.1, + "water_total": 2996.0, + "average_temperature": 31.2333, + "experience_temperature": 27.2533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T14:30:07.976327+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.7, + "humidity": 76.9, + "water_total": 3015.0, + "average_temperature": 31.1333, + "experience_temperature": 28.3133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T14:40:07.798044+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.6, + "humidity": 78.1, + "water_total": 3024.0, + "average_temperature": 31.2, + "experience_temperature": 29.22, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T14:50:06.021675+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 76.5, + "water_total": 3032.0, + "average_temperature": 30.9333, + "experience_temperature": 30.4333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T15:10:06.475368+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 75.2, + "water_total": 3032.0, + "average_temperature": 30.9667, + "experience_temperature": 30.2067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T15:20:11.606743+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 75.7, + "water_total": 3032.0, + "average_temperature": 30.9667, + "experience_temperature": 32.1067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T15:30:07.924034+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 77.7, + "water_total": 3032.0, + "average_temperature": 31.0, + "experience_temperature": 31.34, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T15:40:08.007845+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 77.2, + "water_total": 3032.0, + "average_temperature": 30.8, + "experience_temperature": 31.04, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T15:50:08.818991+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 78.0, + "water_total": 3032.0, + "average_temperature": 31.0333, + "experience_temperature": 30.8333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T16:10:06.087866+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 78.8, + "water_total": 3032.0, + "average_temperature": 30.8, + "experience_temperature": 30.76, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T16:20:06.335339+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 3032.0, + "average_temperature": 30.6333, + "experience_temperature": 30.8133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T16:30:07.160847+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 77.9, + "water_total": 3032.0, + "average_temperature": 30.8, + "experience_temperature": 31.18, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T16:40:06.319977+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 79.0, + "water_total": 3032.0, + "average_temperature": 30.8667, + "experience_temperature": 32.0667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T16:50:07.229935+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 77.6, + "water_total": 3032.0, + "average_temperature": 30.6, + "experience_temperature": 30.92, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T17:10:06.596657+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 31.1333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T17:20:06.803713+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 77.9, + "water_total": 0.0, + "average_temperature": 30.6667, + "experience_temperature": 31.6467, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T17:30:06.709743+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 79.2, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 31.1733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T17:40:06.340174+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 79.7, + "water_total": 6.0, + "average_temperature": 30.3667, + "experience_temperature": 31.1067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T17:50:06.537903+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 80.6, + "water_total": 10.0, + "average_temperature": 30.5333, + "experience_temperature": 31.4533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:00:07.311765+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.3, + "humidity": 79.5, + "water_total": 17.0, + "average_temperature": 30.8, + "experience_temperature": 30.9, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:10:11.621418+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 32.0, + "average_temperature": 30.6333, + "experience_temperature": 31.5933, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:20:08.147175+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 79.4, + "water_total": 39.0, + "average_temperature": 30.6, + "experience_temperature": 31.88, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:30:06.883175+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 80.2, + "water_total": 39.0, + "average_temperature": 30.8, + "experience_temperature": 31.64, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:40:08.088158+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 83.2, + "water_total": 42.0, + "average_temperature": 30.6667, + "experience_temperature": 33.3067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T18:50:07.454098+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 42.0, + "average_temperature": 30.7, + "experience_temperature": 32.48, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:00:06.212329+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 80.4, + "water_total": 43.0, + "average_temperature": 30.7, + "experience_temperature": 32.78, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:10:06.078950+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 80.4, + "water_total": 43.0, + "average_temperature": 30.5333, + "experience_temperature": 31.4133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:20:06.085307+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 81.7, + "water_total": 43.0, + "average_temperature": 30.3333, + "experience_temperature": 31.4733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:30:06.436893+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 82.1, + "water_total": 43.0, + "average_temperature": 30.5, + "experience_temperature": 31.72, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:40:07.065136+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 82.5, + "water_total": 43.0, + "average_temperature": 30.3667, + "experience_temperature": 32.2667, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T19:50:06.734202+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 82.4, + "water_total": 47.0, + "average_temperature": 30.2333, + "experience_temperature": 31.5133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:00:06.643478+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 82.6, + "water_total": 47.0, + "average_temperature": 30.1, + "experience_temperature": 31.42, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:10:06.240478+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 82.6, + "water_total": 47.0, + "average_temperature": 30.1, + "experience_temperature": 31.42, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:20:06.887375+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 82.3, + "water_total": 47.0, + "average_temperature": 29.8667, + "experience_temperature": 32.3267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:30:06.402165+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 83.6, + "water_total": 47.0, + "average_temperature": 29.6333, + "experience_temperature": 32.3533, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:40:06.531958+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 84.0, + "water_total": 47.0, + "average_temperature": 29.4, + "experience_temperature": 32.2, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T20:50:05.687942+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 47.0, + "average_temperature": 29.2333, + "experience_temperature": 32.2333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:00:08.625649+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.4, + "humidity": 85.2, + "water_total": 47.0, + "average_temperature": 29.1333, + "experience_temperature": 29.7733, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:10:06.362267+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 47.0, + "average_temperature": 28.9333, + "experience_temperature": 32.3933, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:20:06.554010+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 86.2, + "water_total": 47.0, + "average_temperature": 29.0, + "experience_temperature": 32.24, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:30:07.863453+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 88.1, + "water_total": 47.0, + "average_temperature": 29.7667, + "experience_temperature": 33.3867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:40:06.099250+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 47.0, + "average_temperature": 29.2, + "experience_temperature": 32.24, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T21:50:06.928469+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 47.0, + "average_temperature": 29.1333, + "experience_temperature": 32.3333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:00:06.218062+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 86.9, + "water_total": 47.0, + "average_temperature": 29.2, + "experience_temperature": 32.58, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:10:06.219483+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.0, + "humidity": 87.6, + "water_total": 47.0, + "average_temperature": 29.1667, + "experience_temperature": 32.6867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:20:07.625819+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 87.6, + "water_total": 47.0, + "average_temperature": 29.3, + "experience_temperature": 31.62, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:30:06.315244+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 88.8, + "water_total": 47.0, + "average_temperature": 29.4333, + "experience_temperature": 32.5933, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:40:06.080011+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 88.1, + "water_total": 47.0, + "average_temperature": 29.3667, + "experience_temperature": 32.3867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T22:50:06.283793+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 88.1, + "water_total": 47.0, + "average_temperature": 29.3667, + "experience_temperature": 32.3867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:00:06.565681+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 87.0, + "water_total": 47.0, + "average_temperature": 29.1333, + "experience_temperature": 31.3333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:10:06.635072+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 50.0, + "average_temperature": 29.6333, + "experience_temperature": 31.7133, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:20:08.430506+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.6, + "water_total": 51.0, + "average_temperature": 29.6667, + "experience_temperature": 32.1867, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:30:06.877435+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.1, + "humidity": 85.3, + "water_total": 51.0, + "average_temperature": 29.7667, + "experience_temperature": 32.2267, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:40:06.809711+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 85.0, + "water_total": 54.0, + "average_temperature": 29.2333, + "experience_temperature": 31.0333, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-04T23:50:08.097246+07:00", + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 86.2, + "water_total": 55.0, + "average_temperature": 29.2667, + "experience_temperature": 31.3067, + "chill_factor": 6.0 + }, + { + "timestamp": "2026-06-05T00:00:06.405085+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 86.8, + "water_total": 55.0, + "average_temperature": 29.1, + "experience_temperature": 31.8814, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T00:10:06.636626+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.9, + "water_total": 58.0, + "average_temperature": 29.4333, + "experience_temperature": 31.4562, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T00:20:06.211582+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 85.2, + "water_total": 62.0, + "average_temperature": 29.6, + "experience_temperature": 30.9043, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T00:30:07.175822+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 85.0, + "water_total": 63.0, + "average_temperature": 29.2667, + "experience_temperature": 32.2667, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T00:40:06.070882+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 63.0, + "average_temperature": 29.2333, + "experience_temperature": 32.3333, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T00:50:06.623182+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.5, + "water_total": 64.0, + "average_temperature": 29.2, + "experience_temperature": 31.3429, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:00:06.581018+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 86.8, + "water_total": 70.0, + "average_temperature": 29.1, + "experience_temperature": 31.8814, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:10:06.078153+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 85.2, + "water_total": 72.0, + "average_temperature": 29.1, + "experience_temperature": 30.4043, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:20:08.778170+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.3, + "water_total": 86.0, + "average_temperature": 29.3, + "experience_temperature": 31.2029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:30:06.686613+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 85.0, + "water_total": 94.0, + "average_temperature": 28.8, + "experience_temperature": 31.2214, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:40:06.385956+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 86.2, + "water_total": 99.0, + "average_temperature": 28.7333, + "experience_temperature": 30.2376, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T01:50:06.408003+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.6, + "water_total": 107.0, + "average_temperature": 28.7667, + "experience_temperature": 30.9295, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:00:07.294125+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 85.6, + "water_total": 113.0, + "average_temperature": 29.0, + "experience_temperature": 31.5414, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:10:06.673176+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.8, + "water_total": 126.0, + "average_temperature": 28.8, + "experience_temperature": 30.8029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:20:07.006071+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 136.0, + "average_temperature": 28.7667, + "experience_temperature": 30.8895, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:30:06.992405+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.2, + "water_total": 149.0, + "average_temperature": 28.7, + "experience_temperature": 30.9829, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:40:06.271576+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 87.3, + "water_total": 162.0, + "average_temperature": 29.0333, + "experience_temperature": 31.9148, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T02:50:06.403430+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.1, + "water_total": 184.0, + "average_temperature": 29.2333, + "experience_temperature": 31.2962, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:00:06.267435+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 198.0, + "average_temperature": 28.5667, + "experience_temperature": 30.6895, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:10:06.502478+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.2, + "water_total": 210.0, + "average_temperature": 28.2667, + "experience_temperature": 30.5495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:20:06.983043+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.0, + "water_total": 230.0, + "average_temperature": 28.5333, + "experience_temperature": 30.7762, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:30:06.434949+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.8, + "water_total": 236.0, + "average_temperature": 28.4667, + "experience_temperature": 30.6695, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:40:06.479485+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 87.6, + "water_total": 266.0, + "average_temperature": 28.6333, + "experience_temperature": 31.5748, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T03:50:06.367939+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 87.5, + "water_total": 278.0, + "average_temperature": 28.3667, + "experience_temperature": 31.2881, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:00:07.760472+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.1, + "water_total": 297.0, + "average_temperature": 28.3, + "experience_temperature": 30.5629, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:10:06.296267+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 309.0, + "average_temperature": 28.2667, + "experience_temperature": 30.3895, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:20:06.033031+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 87.7, + "water_total": 321.0, + "average_temperature": 28.9, + "experience_temperature": 32.44, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:30:05.778527+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.7, + "water_total": 322.0, + "average_temperature": 28.3333, + "experience_temperature": 30.3162, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:40:05.720835+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 87.0, + "water_total": 337.0, + "average_temperature": 28.2333, + "experience_temperature": 31.0548, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T04:50:05.537686+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 88.1, + "water_total": 345.0, + "average_temperature": 29.0667, + "experience_temperature": 32.6867, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:00:06.857101+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.7, + "water_total": 359.0, + "average_temperature": 28.3333, + "experience_temperature": 30.3162, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:10:05.458947+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.0, + "water_total": 375.0, + "average_temperature": 28.5, + "experience_temperature": 30.7429, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:20:05.601481+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 85.5, + "water_total": 428.0, + "average_temperature": 29.0, + "experience_temperature": 32.1, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:30:05.785389+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 87.3, + "water_total": 467.0, + "average_temperature": 28.5333, + "experience_temperature": 31.9933, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:40:05.447965+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 85.4, + "water_total": 487.0, + "average_temperature": 29.0667, + "experience_temperature": 31.5681, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T05:50:05.754023+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 86.0, + "water_total": 504.0, + "average_temperature": 28.8, + "experience_temperature": 32.0, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:00:05.881353+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 87.1, + "water_total": 532.0, + "average_temperature": 28.5333, + "experience_temperature": 31.3748, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:10:05.344139+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 84.5, + "water_total": 576.0, + "average_temperature": 28.6, + "experience_temperature": 30.3429, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:20:05.816360+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 83.9, + "water_total": 597.0, + "average_temperature": 29.0, + "experience_temperature": 30.0443, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:30:05.362008+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 87.2, + "water_total": 607.0, + "average_temperature": 29.2667, + "experience_temperature": 32.7067, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:40:05.293211+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.1, + "water_total": 639.0, + "average_temperature": 29.0333, + "experience_temperature": 31.2962, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T06:50:05.761442+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.5, + "water_total": 669.0, + "average_temperature": 29.0, + "experience_temperature": 31.1429, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:00:05.569843+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.2, + "water_total": 688.0, + "average_temperature": 28.8667, + "experience_temperature": 30.7495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:10:05.959182+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.4, + "water_total": 700.0, + "average_temperature": 28.7667, + "experience_temperature": 30.8895, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:20:05.642480+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 86.1, + "water_total": 722.0, + "average_temperature": 28.9333, + "experience_temperature": 30.9962, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:30:06.084932+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 87.2, + "water_total": 756.0, + "average_temperature": 29.6667, + "experience_temperature": 31.9495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:40:05.526899+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.8, + "water_total": 775.0, + "average_temperature": 29.7, + "experience_temperature": 31.7029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T07:50:05.965912+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 85.8, + "water_total": 775.0, + "average_temperature": 29.7, + "experience_temperature": 31.7029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:00:07.519651+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 85.5, + "water_total": 820.0, + "average_temperature": 30.5667, + "experience_temperature": 33.0881, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:10:06.244960+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 82.4, + "water_total": 844.0, + "average_temperature": 30.8333, + "experience_temperature": 31.5776, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:20:05.966177+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 82.4, + "water_total": 844.0, + "average_temperature": 30.8333, + "experience_temperature": 31.5776, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:30:05.212956+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 83.2, + "water_total": 870.0, + "average_temperature": 30.9333, + "experience_temperature": 32.9948, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:40:06.261183+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.4, + "humidity": 82.5, + "water_total": 883.0, + "average_temperature": 31.0667, + "experience_temperature": 31.2524, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T08:50:05.891416+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 80.9, + "water_total": 891.0, + "average_temperature": 31.0667, + "experience_temperature": 29.7752, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:00:06.346019+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.7, + "humidity": 78.7, + "water_total": 895.0, + "average_temperature": 31.1667, + "experience_temperature": 28.8567, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:10:10.392155+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 78.5, + "water_total": 895.0, + "average_temperature": 31.5667, + "experience_temperature": 29.7952, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:20:05.930325+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 77.6, + "water_total": 899.0, + "average_temperature": 31.9, + "experience_temperature": 29.9486, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:30:05.847225+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 78.0, + "water_total": 901.0, + "average_temperature": 31.9667, + "experience_temperature": 30.0952, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:40:06.209278+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 75.4, + "water_total": 901.0, + "average_temperature": 32.0333, + "experience_temperature": 28.4848, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T09:50:06.670045+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 75.0, + "water_total": 902.0, + "average_temperature": 32.1, + "experience_temperature": 26.7357, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:00:06.082432+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 75.8, + "water_total": 902.0, + "average_temperature": 32.5, + "experience_temperature": 27.2957, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:10:05.685618+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 73.7, + "water_total": 902.0, + "average_temperature": 32.1, + "experience_temperature": 25.8971, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:20:07.678158+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 73.4, + "water_total": 906.0, + "average_temperature": 32.6667, + "experience_temperature": 26.9824, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:30:06.530227+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 73.2, + "water_total": 908.0, + "average_temperature": 32.5667, + "experience_temperature": 26.8424, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:40:05.828935+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 73.2, + "water_total": 908.0, + "average_temperature": 32.5667, + "experience_temperature": 26.8424, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T10:50:06.213626+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 72.9, + "water_total": 910.0, + "average_temperature": 32.9667, + "experience_temperature": 26.6038, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:00:06.209315+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.5, + "humidity": 70.8, + "water_total": 911.0, + "average_temperature": 33.6333, + "experience_temperature": 25.1148, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:10:07.211503+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.6, + "humidity": 70.4, + "water_total": 912.0, + "average_temperature": 33.5667, + "experience_temperature": 24.3895, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:20:06.059715+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.3, + "humidity": 68.0, + "water_total": 913.0, + "average_temperature": 33.7, + "experience_temperature": 25.7786, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:30:06.756352+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.8, + "humidity": 66.7, + "water_total": 913.0, + "average_temperature": 33.7333, + "experience_temperature": 22.659, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:40:06.113807+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.3, + "humidity": 68.9, + "water_total": 913.0, + "average_temperature": 33.6333, + "experience_temperature": 25.8919, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T11:50:07.453591+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 70.8, + "water_total": 913.0, + "average_temperature": 32.9667, + "experience_temperature": 26.7624, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:00:06.451218+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.8, + "humidity": 69.0, + "water_total": 913.0, + "average_temperature": 33.6333, + "experience_temperature": 23.019, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:10:06.654042+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 69.2, + "water_total": 913.0, + "average_temperature": 33.7667, + "experience_temperature": 23.771, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:20:06.128354+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.9, + "humidity": 68.9, + "water_total": 913.0, + "average_temperature": 33.8667, + "experience_temperature": 22.6538, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:30:06.075263+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 67.9, + "water_total": 913.0, + "average_temperature": 33.4333, + "experience_temperature": 26.0705, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:40:07.726386+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.8, + "humidity": 69.3, + "water_total": 913.0, + "average_temperature": 33.7667, + "experience_temperature": 23.2124, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T12:50:06.551912+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 913.0, + "average_temperature": 33.9333, + "experience_temperature": 22.4805, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:00:06.083686+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 68.8, + "water_total": 913.0, + "average_temperature": 33.8333, + "experience_temperature": 23.7576, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:10:06.235133+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.6, + "humidity": 68.2, + "water_total": 915.0, + "average_temperature": 33.8, + "experience_temperature": 24.1829, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:20:06.343701+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 68.3, + "water_total": 915.0, + "average_temperature": 33.6667, + "experience_temperature": 23.491, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:30:06.222688+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.4, + "humidity": 69.4, + "water_total": 915.0, + "average_temperature": 33.1667, + "experience_temperature": 24.9467, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:40:07.358949+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.4, + "humidity": 69.4, + "water_total": 915.0, + "average_temperature": 33.1667, + "experience_temperature": 24.9467, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T13:50:05.600527+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.6, + "humidity": 68.5, + "water_total": 915.0, + "average_temperature": 33.5333, + "experience_temperature": 23.9762, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T14:10:06.132395+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.3, + "humidity": 68.1, + "water_total": 917.0, + "average_temperature": 33.4333, + "experience_temperature": 25.5319, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T14:20:06.308099+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 66.3, + "water_total": 917.0, + "average_temperature": 33.7333, + "experience_temperature": 23.1576, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T14:30:07.218197+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.6, + "humidity": 66.7, + "water_total": 917.0, + "average_temperature": 33.7, + "experience_temperature": 23.7829, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T14:40:06.443106+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 66.5, + "water_total": 917.0, + "average_temperature": 33.5667, + "experience_temperature": 23.031, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T14:50:06.242049+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.7, + "humidity": 66.3, + "water_total": 917.0, + "average_temperature": 33.7, + "experience_temperature": 23.1243, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T15:10:06.865599+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.6, + "humidity": 66.8, + "water_total": 918.0, + "average_temperature": 33.7, + "experience_temperature": 23.8029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T15:20:06.083242+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 64.7, + "water_total": 919.0, + "average_temperature": 33.3333, + "experience_temperature": 25.3305, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T15:30:07.373877+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.4, + "humidity": 67.3, + "water_total": 919.0, + "average_temperature": 33.2, + "experience_temperature": 24.56, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T15:40:07.104561+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 68.0, + "water_total": 919.0, + "average_temperature": 33.3, + "experience_temperature": 26.5357, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T15:50:06.551054+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.1, + "humidity": 68.0, + "water_total": 919.0, + "average_temperature": 33.3, + "experience_temperature": 26.5357, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T16:10:06.146199+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.3, + "humidity": 71.4, + "water_total": 919.0, + "average_temperature": 32.9667, + "experience_temperature": 25.7252, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T16:20:07.570728+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 72.6, + "water_total": 919.0, + "average_temperature": 32.7, + "experience_temperature": 26.2771, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T16:30:07.538781+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 72.9, + "water_total": 919.0, + "average_temperature": 32.6, + "experience_temperature": 26.2371, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T16:40:06.830621+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 73.1, + "water_total": 919.0, + "average_temperature": 32.5, + "experience_temperature": 26.1771, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T16:50:06.813397+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 72.7, + "water_total": 919.0, + "average_temperature": 32.4, + "experience_temperature": 25.9971, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T17:10:06.242520+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.3, + "humidity": 74.1, + "water_total": 0.0, + "average_temperature": 32.0333, + "experience_temperature": 25.3319, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T17:20:07.654384+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 1.2, + "humidity": 73.5, + "water_total": 0.0, + "average_temperature": 31.9333, + "experience_temperature": 25.6905, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T17:30:05.894966+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.7, + "humidity": 73.6, + "water_total": 0.0, + "average_temperature": 31.8333, + "experience_temperature": 28.5033, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T17:40:05.841203+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 74.2, + "water_total": 0.0, + "average_temperature": 31.8, + "experience_temperature": 28.0114, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T17:50:05.786652+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 75.2, + "water_total": 0.0, + "average_temperature": 31.5667, + "experience_temperature": 27.9781, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:00:06.360981+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.7, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 31.3333, + "experience_temperature": 28.6233, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:10:06.349757+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 31.0667, + "experience_temperature": 27.7781, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:20:06.553756+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 76.6, + "water_total": 0.0, + "average_temperature": 30.9, + "experience_temperature": 27.5914, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:30:06.488572+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 78.3, + "water_total": 0.0, + "average_temperature": 31.0333, + "experience_temperature": 29.2219, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:40:06.405204+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.8, + "humidity": 76.3, + "water_total": 0.0, + "average_temperature": 30.9333, + "experience_temperature": 27.5648, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T18:50:06.355426+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.7, + "humidity": 78.1, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 28.4033, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:00:06.772128+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 78.6, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 31.8748, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:10:06.127166+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 80.0, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 32.2214, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:20:06.187729+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 78.2, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 31.8614, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:30:06.056115+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.7, + "humidity": 78.4, + "water_total": 0.0, + "average_temperature": 30.8667, + "experience_temperature": 28.4967, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:40:06.559904+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 79.3, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 32.0148, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T19:50:06.097745+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 77.5, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 31.0762, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:00:06.569520+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 77.1, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 31.6748, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:10:05.770165+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.5, + "humidity": 77.9, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 29.5205, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:20:07.287108+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 78.2, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 31.2162, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:30:06.148635+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 78.1, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 30.5843, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:40:06.175519+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 77.1, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 31.6414, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T20:50:06.534661+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 77.1, + "water_total": 0.0, + "average_temperature": 30.8333, + "experience_temperature": 28.7819, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:00:06.117848+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 79.4, + "water_total": 0.0, + "average_temperature": 30.7667, + "experience_temperature": 32.0681, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:10:06.111476+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 78.8, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 31.4029, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:20:09.245302+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 79.3, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 31.4362, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:30:06.962357+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.0, + "humidity": 79.6, + "water_total": 0.0, + "average_temperature": 30.6, + "experience_temperature": 32.52, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:40:08.009196+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 79.9, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 31.3562, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T21:50:06.431656+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 79.6, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 31.1629, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:00:06.085356+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 32.2348, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:10:06.027180+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 81.8, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 32.1814, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:20:06.334308+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 80.6, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 30.651, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:30:06.720296+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.3, + "humidity": 80.6, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 30.651, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:40:06.285141+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.6, + "humidity": 82.2, + "water_total": 4.0, + "average_temperature": 30.8667, + "experience_temperature": 29.8352, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T22:50:06.438855+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 4.0, + "average_temperature": 30.1667, + "experience_temperature": 31.1695, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:00:05.823465+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 82.7, + "water_total": 6.0, + "average_temperature": 30.2667, + "experience_temperature": 31.6495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:10:06.027248+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 82.7, + "water_total": 6.0, + "average_temperature": 30.2667, + "experience_temperature": 31.6495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:20:06.244789+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 23.0, + "average_temperature": 30.1667, + "experience_temperature": 31.2495, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:30:06.268302+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 82.4, + "water_total": 23.0, + "average_temperature": 29.9, + "experience_temperature": 31.8014, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:40:05.873190+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.1, + "humidity": 83.4, + "water_total": 23.0, + "average_temperature": 29.8667, + "experience_temperature": 31.9681, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-05T23:50:05.792054+07:00", + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 83.0, + "water_total": 23.0, + "average_temperature": 29.7667, + "experience_temperature": 31.2095, + "chill_factor": 5.7857 + }, + { + "timestamp": "2026-06-06T00:00:05.805404+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.2, + "water_total": 26.0, + "average_temperature": 29.7667, + "experience_temperature": 31.8495, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T00:10:06.034170+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.4, + "water_total": 29.0, + "average_temperature": 30.0, + "experience_temperature": 31.5657, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T00:20:06.544264+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 82.7, + "water_total": 34.0, + "average_temperature": 30.0667, + "experience_temperature": 32.0495, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T00:30:06.255181+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.5, + "water_total": 34.0, + "average_temperature": 29.9333, + "experience_temperature": 32.0762, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T00:40:05.999385+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.1, + "water_total": 34.0, + "average_temperature": 29.7333, + "experience_temperature": 31.039, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T00:50:06.805328+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.9, + "water_total": 34.0, + "average_temperature": 29.8, + "experience_temperature": 31.2657, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:00:06.596243+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 82.5, + "water_total": 34.0, + "average_temperature": 29.7, + "experience_temperature": 32.2, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:10:06.065663+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.0, + "water_total": 34.0, + "average_temperature": 29.6333, + "experience_temperature": 31.119, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:20:06.145418+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.0, + "water_total": 34.0, + "average_temperature": 29.6, + "experience_temperature": 30.8857, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:30:07.654497+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.9, + "water_total": 34.0, + "average_temperature": 29.5, + "experience_temperature": 30.9657, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:40:07.601682+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.6, + "water_total": 34.0, + "average_temperature": 29.6667, + "experience_temperature": 31.8295, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T01:50:07.384768+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.7, + "water_total": 34.0, + "average_temperature": 29.4333, + "experience_temperature": 31.059, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:00:05.978364+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 83.8, + "water_total": 34.0, + "average_temperature": 29.6, + "experience_temperature": 30.6886, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:10:06.197939+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.6, + "water_total": 34.0, + "average_temperature": 30.1333, + "experience_temperature": 31.939, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:20:06.367741+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 34.0, + "average_temperature": 29.4, + "experience_temperature": 30.8457, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:30:06.661674+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.7, + "water_total": 34.0, + "average_temperature": 29.0, + "experience_temperature": 31.1829, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:40:06.248924+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 34.0, + "average_temperature": 29.8, + "experience_temperature": 31.1857, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T02:50:05.900087+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.7, + "water_total": 34.0, + "average_temperature": 29.5, + "experience_temperature": 31.3257, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:00:06.466167+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 87.0, + "water_total": 34.0, + "average_temperature": 29.4, + "experience_temperature": 32.8, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:10:07.987008+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.3, + "water_total": 34.0, + "average_temperature": 29.3333, + "experience_temperature": 30.879, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:20:07.214967+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.6, + "water_total": 34.0, + "average_temperature": 29.4, + "experience_temperature": 31.0057, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:30:06.555377+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 85.3, + "water_total": 34.0, + "average_temperature": 29.1333, + "experience_temperature": 31.6362, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:40:06.435845+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 85.2, + "water_total": 34.0, + "average_temperature": 29.1333, + "experience_temperature": 31.059, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T03:50:07.333367+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 86.6, + "water_total": 34.0, + "average_temperature": 29.5667, + "experience_temperature": 31.7724, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:00:06.370337+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 83.6, + "water_total": 34.0, + "average_temperature": 29.5, + "experience_temperature": 31.1057, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:10:06.347164+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.9, + "water_total": 34.0, + "average_temperature": 28.8333, + "experience_temperature": 31.0562, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:20:06.774517+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 85.2, + "water_total": 34.0, + "average_temperature": 28.7, + "experience_temperature": 31.1829, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:30:07.839875+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 85.0, + "water_total": 34.0, + "average_temperature": 28.6667, + "experience_temperature": 30.5524, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:40:06.790264+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 85.3, + "water_total": 34.0, + "average_temperature": 28.5667, + "experience_temperature": 30.5124, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T04:50:06.365716+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 85.3, + "water_total": 34.0, + "average_temperature": 28.6333, + "experience_temperature": 30.579, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:00:06.965423+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 86.6, + "water_total": 34.0, + "average_temperature": 28.7333, + "experience_temperature": 30.939, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:10:06.857435+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 86.1, + "water_total": 34.0, + "average_temperature": 29.0667, + "experience_temperature": 31.1724, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:20:06.112441+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 85.2, + "water_total": 34.0, + "average_temperature": 29.6, + "experience_temperature": 32.64, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:30:06.644249+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 86.7, + "water_total": 34.0, + "average_temperature": 29.2, + "experience_temperature": 31.9829, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:40:06.955219+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 84.4, + "water_total": 34.0, + "average_temperature": 29.2333, + "experience_temperature": 30.4419, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T05:50:06.455698+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.3, + "water_total": 34.0, + "average_temperature": 29.0333, + "experience_temperature": 30.779, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:00:06.462656+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.2, + "water_total": 34.0, + "average_temperature": 29.3, + "experience_temperature": 31.0257, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:10:06.680003+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.6, + "water_total": 34.0, + "average_temperature": 29.5333, + "experience_temperature": 31.339, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:20:06.822801+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 86.4, + "water_total": 41.0, + "average_temperature": 29.2, + "experience_temperature": 32.48, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:30:06.350502+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 85.5, + "water_total": 42.0, + "average_temperature": 29.5, + "experience_temperature": 31.4857, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:40:09.148272+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 42.0, + "average_temperature": 29.4, + "experience_temperature": 32.58, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T06:50:06.019827+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.5, + "water_total": 42.0, + "average_temperature": 29.8333, + "experience_temperature": 31.619, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:00:06.847413+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.2, + "water_total": 49.0, + "average_temperature": 30.0667, + "experience_temperature": 31.3924, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:10:05.980532+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.6, + "water_total": 56.0, + "average_temperature": 29.9, + "experience_temperature": 31.3057, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:20:07.128658+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 84.1, + "water_total": 58.0, + "average_temperature": 30.1667, + "experience_temperature": 31.8724, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:30:06.202586+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 82.2, + "water_total": 70.0, + "average_temperature": 30.3333, + "experience_temperature": 31.659, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:40:07.032872+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 83.9, + "water_total": 82.0, + "average_temperature": 30.4667, + "experience_temperature": 32.6895, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T07:50:06.493347+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 98.0, + "average_temperature": 30.5667, + "experience_temperature": 31.6324, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:00:16.507946+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 98.0, + "average_temperature": 30.5667, + "experience_temperature": 31.6324, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:10:06.880895+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.4, + "humidity": 81.6, + "water_total": 123.0, + "average_temperature": 30.6, + "experience_temperature": 30.6914, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:20:06.481055+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.0, + "humidity": 81.9, + "water_total": 163.0, + "average_temperature": 30.7, + "experience_temperature": 33.08, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:30:07.377405+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 80.5, + "water_total": 188.0, + "average_temperature": 31.0, + "experience_temperature": 28.6429, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:40:07.531375+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 78.2, + "water_total": 225.0, + "average_temperature": 31.2667, + "experience_temperature": 28.4495, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T08:50:06.409707+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 75.4, + "water_total": 277.0, + "average_temperature": 31.5667, + "experience_temperature": 28.1895, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:00:07.011092+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 77.5, + "water_total": 324.0, + "average_temperature": 31.6, + "experience_temperature": 29.2, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:10:06.999921+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 76.3, + "water_total": 359.0, + "average_temperature": 31.5, + "experience_temperature": 28.3029, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:20:07.146947+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.5, + "humidity": 77.8, + "water_total": 405.0, + "average_temperature": 31.6667, + "experience_temperature": 30.441, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:30:06.714446+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 77.4, + "water_total": 467.0, + "average_temperature": 31.5667, + "experience_temperature": 29.1467, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:40:06.393591+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.2, + "humidity": 74.8, + "water_total": 509.0, + "average_temperature": 32.0667, + "experience_temperature": 26.341, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T09:50:06.622947+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.4, + "humidity": 72.9, + "water_total": 545.0, + "average_temperature": 32.5333, + "experience_temperature": 25.3133, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:00:06.099467+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.2, + "humidity": 72.7, + "water_total": 591.0, + "average_temperature": 32.5667, + "experience_temperature": 26.421, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:10:07.062624+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.4, + "humidity": 71.3, + "water_total": 633.0, + "average_temperature": 33.1, + "experience_temperature": 25.56, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:20:05.814586+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.1, + "humidity": 73.4, + "water_total": 689.0, + "average_temperature": 33.0, + "experience_temperature": 27.5514, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:30:05.172006+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 72.1, + "water_total": 728.0, + "average_temperature": 32.4333, + "experience_temperature": 25.6105, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:40:06.231061+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 72.3, + "water_total": 766.0, + "average_temperature": 32.0333, + "experience_temperature": 25.2505, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T10:50:06.713676+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 72.1, + "water_total": 809.0, + "average_temperature": 32.4667, + "experience_temperature": 25.6438, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:00:06.536938+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 72.3, + "water_total": 838.0, + "average_temperature": 32.8333, + "experience_temperature": 26.0505, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:10:05.994074+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 70.7, + "water_total": 901.0, + "average_temperature": 33.0, + "experience_temperature": 25.8971, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:20:07.427923+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.7, + "humidity": 69.4, + "water_total": 970.0, + "average_temperature": 33.2667, + "experience_temperature": 23.6752, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:30:05.246582+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.7, + "humidity": 69.7, + "water_total": 1021.0, + "average_temperature": 33.2667, + "experience_temperature": 23.7352, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:40:06.214633+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 1092.0, + "average_temperature": 33.9667, + "experience_temperature": 22.921, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T11:50:05.193229+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.8, + "humidity": 67.6, + "water_total": 1151.0, + "average_temperature": 33.7, + "experience_temperature": 23.1914, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:00:06.148899+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.9, + "humidity": 64.9, + "water_total": 1226.0, + "average_temperature": 33.8333, + "experience_temperature": 22.2276, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:10:07.526614+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.8, + "humidity": 65.4, + "water_total": 1287.0, + "average_temperature": 33.8333, + "experience_temperature": 22.8848, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:20:06.458897+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.1, + "humidity": 63.2, + "water_total": 1366.0, + "average_temperature": 34.4333, + "experience_temperature": 21.3733, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:30:06.022914+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.2, + "humidity": 63.6, + "water_total": 1420.0, + "average_temperature": 34.5333, + "experience_temperature": 20.9962, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:40:06.827047+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.9, + "humidity": 62.0, + "water_total": 1494.0, + "average_temperature": 34.7, + "experience_temperature": 22.5143, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T12:50:05.771351+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.2, + "humidity": 62.2, + "water_total": 1563.0, + "average_temperature": 34.8333, + "experience_temperature": 21.0162, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:00:06.199804+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 61.4, + "water_total": 1634.0, + "average_temperature": 34.4, + "experience_temperature": 21.5371, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:10:06.102736+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.1, + "humidity": 62.9, + "water_total": 1701.0, + "average_temperature": 34.6667, + "experience_temperature": 21.5467, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:20:06.320590+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 62.8, + "water_total": 1768.0, + "average_temperature": 34.6667, + "experience_temperature": 22.0838, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:30:07.470923+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.2, + "humidity": 62.0, + "water_total": 1826.0, + "average_temperature": 34.5333, + "experience_temperature": 20.6762, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:40:05.592487+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.8, + "humidity": 61.8, + "water_total": 1895.0, + "average_temperature": 34.8667, + "experience_temperature": 23.1981, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T13:50:06.569456+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.2, + "humidity": 59.8, + "water_total": 1965.0, + "average_temperature": 34.6333, + "experience_temperature": 20.3362, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T14:20:06.138431+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 59.5, + "water_total": 2165.0, + "average_temperature": 34.8667, + "experience_temperature": 21.6238, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T14:30:05.619035+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 60.2, + "water_total": 2230.0, + "average_temperature": 34.7667, + "experience_temperature": 21.6638, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T14:40:06.320959+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 59.8, + "water_total": 2289.0, + "average_temperature": 34.8333, + "experience_temperature": 21.6505, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T14:50:08.657130+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.8, + "humidity": 59.0, + "water_total": 2337.0, + "average_temperature": 34.7, + "experience_temperature": 22.4714, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T15:10:07.140647+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.1, + "humidity": 60.4, + "water_total": 2494.0, + "average_temperature": 34.7333, + "experience_temperature": 21.1133, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T15:20:05.699628+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.3, + "humidity": 59.0, + "water_total": 2548.0, + "average_temperature": 34.5, + "experience_temperature": 19.4857, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T15:30:05.149878+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.1, + "humidity": 60.7, + "water_total": 2619.0, + "average_temperature": 34.5333, + "experience_temperature": 20.9733, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T15:40:06.990185+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.3, + "humidity": 61.7, + "water_total": 2684.0, + "average_temperature": 34.2, + "experience_temperature": 19.7257, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T15:50:06.183151+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 2.0, + "humidity": 61.8, + "water_total": 2745.0, + "average_temperature": 34.3, + "experience_temperature": 21.5171, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T16:10:07.568511+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.6, + "humidity": 61.9, + "water_total": 2864.0, + "average_temperature": 33.6667, + "experience_temperature": 23.1324, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T16:20:07.278175+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.8, + "humidity": 65.9, + "water_total": 2922.0, + "average_temperature": 33.3333, + "experience_temperature": 22.4848, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T16:30:05.628003+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.2, + "humidity": 67.5, + "water_total": 2991.0, + "average_temperature": 33.0333, + "experience_temperature": 25.8476, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T16:40:05.836088+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 68.8, + "water_total": 3080.0, + "average_temperature": 32.8667, + "experience_temperature": 25.3838, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T16:50:06.076492+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 69.3, + "water_total": 3141.0, + "average_temperature": 32.7, + "experience_temperature": 25.3171, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T17:10:05.974105+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.5, + "humidity": 70.4, + "water_total": 61.0, + "average_temperature": 32.3, + "experience_temperature": 24.0229, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T17:20:06.089349+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 72.3, + "water_total": 124.0, + "average_temperature": 32.1, + "experience_temperature": 25.3171, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T17:30:05.835610+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.4, + "humidity": 72.2, + "water_total": 179.0, + "average_temperature": 31.8667, + "experience_temperature": 24.5067, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T17:40:05.792603+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.4, + "humidity": 72.2, + "water_total": 179.0, + "average_temperature": 31.8667, + "experience_temperature": 24.5067, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T17:50:07.621655+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.2, + "humidity": 73.8, + "water_total": 307.0, + "average_temperature": 31.6333, + "experience_temperature": 25.7076, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:00:06.027067+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 1.3, + "humidity": 73.7, + "water_total": 371.0, + "average_temperature": 31.5333, + "experience_temperature": 25.0305, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:10:06.186626+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 74.3, + "water_total": 443.0, + "average_temperature": 31.4667, + "experience_temperature": 27.8695, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:20:05.820104+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.6, + "humidity": 76.6, + "water_total": 512.0, + "average_temperature": 31.3333, + "experience_temperature": 29.3105, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:30:06.427386+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 75.5, + "water_total": 591.0, + "average_temperature": 31.3667, + "experience_temperature": 28.5667, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:40:06.340596+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 76.3, + "water_total": 660.0, + "average_temperature": 31.2, + "experience_temperature": 28.56, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T18:50:05.796907+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 76.5, + "water_total": 731.0, + "average_temperature": 31.1, + "experience_temperature": 28.5, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:00:07.227635+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 76.0, + "water_total": 798.0, + "average_temperature": 30.9667, + "experience_temperature": 27.7095, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:10:05.760049+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.6, + "humidity": 75.2, + "water_total": 856.0, + "average_temperature": 30.8667, + "experience_temperature": 28.5638, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:20:05.826838+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.6, + "humidity": 76.2, + "water_total": 923.0, + "average_temperature": 30.8, + "experience_temperature": 28.6971, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:30:05.619405+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 74.8, + "water_total": 992.0, + "average_temperature": 30.7, + "experience_temperature": 27.76, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:40:06.346138+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 76.0, + "water_total": 1057.0, + "average_temperature": 30.5667, + "experience_temperature": 27.3095, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T19:50:05.561786+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.8, + "humidity": 75.4, + "water_total": 1118.0, + "average_temperature": 30.6, + "experience_temperature": 27.2229, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:00:06.035153+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 76.4, + "water_total": 1187.0, + "average_temperature": 30.5, + "experience_temperature": 30.1086, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:10:06.187236+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 74.9, + "water_total": 1253.0, + "average_temperature": 30.5333, + "experience_temperature": 27.6133, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:20:06.171273+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 74.7, + "water_total": 1314.0, + "average_temperature": 30.4667, + "experience_temperature": 29.7352, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:30:05.823294+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 74.7, + "water_total": 1314.0, + "average_temperature": 30.4667, + "experience_temperature": 29.7352, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:40:06.537152+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 75.1, + "water_total": 1462.0, + "average_temperature": 30.5, + "experience_temperature": 30.4057, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T20:50:06.098851+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 76.9, + "water_total": 1537.0, + "average_temperature": 30.5333, + "experience_temperature": 30.799, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:00:06.628344+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 74.3, + "water_total": 1609.0, + "average_temperature": 30.4333, + "experience_temperature": 30.179, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:10:05.848205+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.7, + "humidity": 75.9, + "water_total": 1671.0, + "average_temperature": 30.5333, + "experience_temperature": 27.8133, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:20:06.209887+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.6, + "humidity": 77.4, + "water_total": 1733.0, + "average_temperature": 30.6, + "experience_temperature": 28.7371, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:30:06.708286+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 74.2, + "water_total": 1808.0, + "average_temperature": 30.4667, + "experience_temperature": 30.7495, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:40:06.348193+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 75.2, + "water_total": 1889.0, + "average_temperature": 30.4333, + "experience_temperature": 29.8019, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T21:50:05.814380+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 77.3, + "water_total": 1967.0, + "average_temperature": 30.5, + "experience_temperature": 31.4029, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:00:06.153540+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 76.4, + "water_total": 2037.0, + "average_temperature": 30.4, + "experience_temperature": 31.1229, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:10:06.111691+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 76.2, + "water_total": 2119.0, + "average_temperature": 30.5, + "experience_temperature": 31.1829, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:20:07.629019+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 74.9, + "water_total": 2192.0, + "average_temperature": 30.4, + "experience_temperature": 30.2657, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:30:05.997623+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 76.2, + "water_total": 2265.0, + "average_temperature": 30.4333, + "experience_temperature": 31.1162, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:40:05.500989+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 77.1, + "water_total": 2339.0, + "average_temperature": 30.3667, + "experience_temperature": 30.1152, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T22:50:06.138437+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 75.6, + "water_total": 2406.0, + "average_temperature": 30.3667, + "experience_temperature": 29.8152, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:00:05.818190+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 78.7, + "water_total": 2445.0, + "average_temperature": 30.2, + "experience_temperature": 30.8257, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:10:05.841218+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 77.1, + "water_total": 2484.0, + "average_temperature": 29.9, + "experience_temperature": 30.2057, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:20:06.197408+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 77.4, + "water_total": 2518.0, + "average_temperature": 29.8, + "experience_temperature": 30.1657, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:30:06.513904+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.2, + "humidity": 78.7, + "water_total": 2552.0, + "average_temperature": 29.6333, + "experience_temperature": 30.259, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:40:06.317612+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.3, + "humidity": 78.7, + "water_total": 2586.0, + "average_temperature": 29.5333, + "experience_temperature": 29.6019, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-06T23:50:05.803719+07:00", + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 79.0, + "water_total": 2619.0, + "average_temperature": 29.3, + "experience_temperature": 30.5429, + "chill_factor": 5.5714 + }, + { + "timestamp": "2026-06-07T00:00:06.347733+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.0, + "water_total": 2660.0, + "average_temperature": 29.3, + "experience_temperature": 30.2286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T00:10:05.729304+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.0, + "water_total": 2660.0, + "average_temperature": 29.3, + "experience_temperature": 30.2286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T00:20:05.795975+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 79.7, + "water_total": 2800.0, + "average_temperature": 29.9333, + "experience_temperature": 30.2662, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T00:30:05.913509+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 78.9, + "water_total": 2881.0, + "average_temperature": 29.5667, + "experience_temperature": 30.811, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T00:40:05.807336+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 78.8, + "water_total": 2953.0, + "average_temperature": 29.4333, + "experience_temperature": 30.1219, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T00:50:07.086617+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 78.6, + "water_total": 3022.0, + "average_temperature": 29.4, + "experience_temperature": 30.0486, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:00:05.810575+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.0, + "humidity": 80.2, + "water_total": 3100.0, + "average_temperature": 29.4667, + "experience_temperature": 31.5067, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:10:05.692397+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 78.6, + "water_total": 3170.0, + "average_temperature": 29.4667, + "experience_temperature": 30.1152, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:20:06.286493+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 3239.0, + "average_temperature": 30.1, + "experience_temperature": 31.2686, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:30:05.878670+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 3313.0, + "average_temperature": 29.4, + "experience_temperature": 30.4686, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:40:05.527814+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.2, + "water_total": 3371.0, + "average_temperature": 28.9667, + "experience_temperature": 30.471, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T01:50:06.530364+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.9, + "water_total": 3420.0, + "average_temperature": 28.9333, + "experience_temperature": 30.2419, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:00:05.873685+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.1, + "water_total": 3470.0, + "average_temperature": 28.8, + "experience_temperature": 29.9486, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:10:06.382571+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 79.6, + "water_total": 3527.0, + "average_temperature": 28.7, + "experience_temperature": 30.0843, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:20:05.589511+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 79.7, + "water_total": 3576.0, + "average_temperature": 28.6333, + "experience_temperature": 30.0376, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:30:05.486648+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 3640.0, + "average_temperature": 28.5667, + "experience_temperature": 29.6552, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:40:06.067464+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.0, + "water_total": 3689.0, + "average_temperature": 28.4, + "experience_temperature": 29.5286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T02:50:06.599449+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 82.0, + "water_total": 3745.0, + "average_temperature": 28.6, + "experience_temperature": 29.9286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:00:06.791374+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 80.3, + "water_total": 3829.0, + "average_temperature": 29.0333, + "experience_temperature": 29.4862, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:10:06.131344+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.6, + "water_total": 3882.0, + "average_temperature": 28.1667, + "experience_temperature": 29.0152, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:20:07.272732+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 3939.0, + "average_temperature": 28.7333, + "experience_temperature": 29.7619, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:30:07.338707+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 3992.0, + "average_temperature": 28.3, + "experience_temperature": 29.3686, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:40:07.482693+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 4049.0, + "average_temperature": 28.2333, + "experience_temperature": 29.6619, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T03:50:05.959122+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.1, + "water_total": 4102.0, + "average_temperature": 28.7667, + "experience_temperature": 30.451, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:00:05.922466+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 4168.0, + "average_temperature": 28.2667, + "experience_temperature": 29.2952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:10:06.188465+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 4220.0, + "average_temperature": 27.8667, + "experience_temperature": 29.0952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:20:07.434341+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.0, + "water_total": 4253.0, + "average_temperature": 28.1333, + "experience_temperature": 29.5976, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:30:06.775732+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.0, + "humidity": 81.5, + "water_total": 4288.0, + "average_temperature": 28.7667, + "experience_temperature": 31.0667, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:40:05.758188+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 4319.0, + "average_temperature": 28.1, + "experience_temperature": 29.1886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T04:50:06.335925+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.8, + "water_total": 4355.0, + "average_temperature": 28.8, + "experience_temperature": 29.8886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:00:06.148430+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.6, + "water_total": 4391.0, + "average_temperature": 28.1333, + "experience_temperature": 29.9176, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:10:07.142321+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 4432.0, + "average_temperature": 29.0667, + "experience_temperature": 30.1352, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:20:06.241677+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.0, + "water_total": 4502.0, + "average_temperature": 28.8333, + "experience_temperature": 30.4976, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:30:06.360406+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.6, + "water_total": 4573.0, + "average_temperature": 28.6333, + "experience_temperature": 29.8819, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:40:06.241267+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 4635.0, + "average_temperature": 27.8667, + "experience_temperature": 28.8952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T05:50:07.826199+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 82.2, + "water_total": 4694.0, + "average_temperature": 28.4333, + "experience_temperature": 29.8019, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:00:06.346308+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.9, + "water_total": 4751.0, + "average_temperature": 28.9, + "experience_temperature": 30.7443, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:10:06.244303+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.8, + "water_total": 4799.0, + "average_temperature": 27.9, + "experience_temperature": 29.1886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:20:06.029483+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.2, + "water_total": 4856.0, + "average_temperature": 28.5667, + "experience_temperature": 30.271, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:30:06.430267+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 81.6, + "water_total": 4938.0, + "average_temperature": 28.2333, + "experience_temperature": 29.4819, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:40:06.144600+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 82.8, + "water_total": 4996.0, + "average_temperature": 27.8, + "experience_temperature": 29.8243, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T06:50:07.009428+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 81.6, + "water_total": 5059.0, + "average_temperature": 28.5, + "experience_temperature": 29.2129, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:00:06.642595+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 82.7, + "water_total": 5116.0, + "average_temperature": 28.8, + "experience_temperature": 30.2686, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:10:05.937011+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 82.1, + "water_total": 5192.0, + "average_temperature": 28.9, + "experience_temperature": 30.7843, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:20:06.082105+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 5248.0, + "average_temperature": 29.3333, + "experience_temperature": 31.8933, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:30:06.477457+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 80.5, + "water_total": 5334.0, + "average_temperature": 29.7333, + "experience_temperature": 30.7619, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:40:05.940379+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.3, + "water_total": 5404.0, + "average_temperature": 29.7333, + "experience_temperature": 31.2576, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T07:50:07.326658+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.4, + "humidity": 80.6, + "water_total": 5462.0, + "average_temperature": 29.8333, + "experience_temperature": 29.8105, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:00:07.485101+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 78.5, + "water_total": 5519.0, + "average_temperature": 29.8, + "experience_temperature": 29.8929, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:10:05.947516+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 78.5, + "water_total": 5519.0, + "average_temperature": 29.8, + "experience_temperature": 29.8929, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:20:06.410455+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 79.8, + "water_total": 5615.0, + "average_temperature": 29.9, + "experience_temperature": 30.2529, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:30:06.993273+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.6, + "humidity": 78.7, + "water_total": 5657.0, + "average_temperature": 30.0667, + "experience_temperature": 28.5924, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:40:06.726690+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.6, + "humidity": 77.5, + "water_total": 5701.0, + "average_temperature": 30.2333, + "experience_temperature": 28.519, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T08:50:07.569642+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 75.9, + "water_total": 5742.0, + "average_temperature": 30.8333, + "experience_temperature": 28.2633, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:00:06.267193+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 75.9, + "water_total": 5742.0, + "average_temperature": 30.8333, + "experience_temperature": 28.2633, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:10:06.069635+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.2, + "humidity": 74.0, + "water_total": 5836.0, + "average_temperature": 31.4, + "experience_temperature": 25.7714, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:20:07.787339+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.1, + "humidity": 71.5, + "water_total": 5874.0, + "average_temperature": 31.5, + "experience_temperature": 25.9071, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:30:06.473989+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.3, + "humidity": 71.4, + "water_total": 5901.0, + "average_temperature": 31.9, + "experience_temperature": 25.2157, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:40:06.868350+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.3, + "humidity": 70.7, + "water_total": 5939.0, + "average_temperature": 31.9333, + "experience_temperature": 25.109, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T09:50:06.459133+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.2, + "humidity": 70.1, + "water_total": 5997.0, + "average_temperature": 32.0333, + "experience_temperature": 25.6248, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:00:06.496191+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.2, + "humidity": 69.6, + "water_total": 6045.0, + "average_temperature": 32.1, + "experience_temperature": 25.5914, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:10:06.453262+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 70.0, + "water_total": 6096.0, + "average_temperature": 32.4667, + "experience_temperature": 23.3595, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:20:06.654790+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.8, + "humidity": 66.9, + "water_total": 6138.0, + "average_temperature": 32.5667, + "experience_temperature": 22.3038, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:30:06.604521+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.6, + "humidity": 64.1, + "water_total": 6183.0, + "average_temperature": 32.5333, + "experience_temperature": 22.7819, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:40:05.940164+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.8, + "humidity": 63.1, + "water_total": 6227.0, + "average_temperature": 32.8667, + "experience_temperature": 21.8438, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T10:50:05.616730+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.8, + "humidity": 62.1, + "water_total": 6266.0, + "average_temperature": 33.4667, + "experience_temperature": 22.2438, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:00:05.831085+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 60.6, + "water_total": 6323.0, + "average_temperature": 33.4333, + "experience_temperature": 22.4462, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:10:07.175194+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 60.6, + "water_total": 6323.0, + "average_temperature": 33.4333, + "experience_temperature": 22.4462, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:20:06.262040+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 59.2, + "water_total": 6417.0, + "average_temperature": 33.7333, + "experience_temperature": 22.4662, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:30:05.881985+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.6, + "humidity": 57.7, + "water_total": 6478.0, + "average_temperature": 33.8667, + "experience_temperature": 22.8352, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:40:06.373373+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 58.7, + "water_total": 6521.0, + "average_temperature": 34.0667, + "experience_temperature": 20.5567, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T11:50:06.296325+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 57.0, + "water_total": 6572.0, + "average_temperature": 33.9333, + "experience_temperature": 22.2262, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:00:06.590067+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 55.7, + "water_total": 6615.0, + "average_temperature": 34.0333, + "experience_temperature": 19.9233, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:10:06.446998+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.3, + "humidity": 57.2, + "water_total": 6661.0, + "average_temperature": 34.2333, + "experience_temperature": 19.3519, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:20:07.724800+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 56.1, + "water_total": 6699.0, + "average_temperature": 34.3333, + "experience_temperature": 19.7676, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:30:07.176510+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.9, + "humidity": 56.5, + "water_total": 6753.0, + "average_temperature": 34.5333, + "experience_temperature": 21.6548, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:40:09.273447+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 55.1, + "water_total": 6806.0, + "average_temperature": 34.3667, + "experience_temperature": 19.601, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T12:50:06.390286+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 54.5, + "water_total": 6850.0, + "average_temperature": 34.7333, + "experience_temperature": 20.3833, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:00:06.870194+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 52.9, + "water_total": 6896.0, + "average_temperature": 34.6667, + "experience_temperature": 19.461, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:10:06.058646+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 53.0, + "water_total": 6943.0, + "average_temperature": 34.3667, + "experience_temperature": 19.181, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:20:06.526335+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 55.2, + "water_total": 6988.0, + "average_temperature": 34.6333, + "experience_temperature": 20.4233, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:30:06.077268+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 55.2, + "water_total": 6988.0, + "average_temperature": 34.6333, + "experience_temperature": 20.4233, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:40:06.405522+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 53.0, + "water_total": 7086.0, + "average_temperature": 34.6, + "experience_temperature": 19.95, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T13:50:08.704220+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.0, + "humidity": 54.4, + "water_total": 7135.0, + "average_temperature": 34.7333, + "experience_temperature": 20.899, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T14:10:06.489714+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 55.1, + "water_total": 7232.0, + "average_temperature": 34.7, + "experience_temperature": 19.9343, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T14:20:07.177006+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.2, + "humidity": 56.5, + "water_total": 7276.0, + "average_temperature": 34.6, + "experience_temperature": 20.1143, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T14:30:08.936312+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.9, + "humidity": 54.8, + "water_total": 7321.0, + "average_temperature": 34.4667, + "experience_temperature": 21.2481, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T14:40:06.757691+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.3, + "humidity": 51.6, + "water_total": 7365.0, + "average_temperature": 34.3667, + "experience_temperature": 18.3652, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T14:50:06.361625+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 51.4, + "water_total": 7409.0, + "average_temperature": 34.4333, + "experience_temperature": 19.4633, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T15:10:06.602340+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.4, + "humidity": 58.0, + "water_total": 7501.0, + "average_temperature": 34.1667, + "experience_temperature": 18.9095, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T15:20:06.547205+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.4, + "humidity": 60.6, + "water_total": 7545.0, + "average_temperature": 33.8667, + "experience_temperature": 19.1295, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T15:30:07.332814+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.8, + "humidity": 60.4, + "water_total": 7580.0, + "average_temperature": 33.6, + "experience_temperature": 22.0371, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T15:40:06.768329+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.9, + "humidity": 61.4, + "water_total": 7619.0, + "average_temperature": 33.4333, + "experience_temperature": 21.5348, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T15:50:06.437918+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.7, + "humidity": 62.1, + "water_total": 7667.0, + "average_temperature": 33.1, + "experience_temperature": 22.4129, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T16:10:06.997384+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 2.1, + "humidity": 62.0, + "water_total": 7754.0, + "average_temperature": 32.6333, + "experience_temperature": 19.7833, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T16:20:07.504740+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.9, + "humidity": 63.2, + "water_total": 7796.0, + "average_temperature": 32.5333, + "experience_temperature": 20.9948, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T16:30:07.487374+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.2, + "humidity": 64.6, + "water_total": 7852.0, + "average_temperature": 32.1667, + "experience_temperature": 24.6581, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T16:40:06.277490+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.4, + "humidity": 65.2, + "water_total": 7900.0, + "average_temperature": 32.0667, + "experience_temperature": 23.6067, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T16:50:06.516250+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.4, + "humidity": 65.2, + "water_total": 7900.0, + "average_temperature": 32.0667, + "experience_temperature": 23.6067, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T17:10:06.033641+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 1.2, + "humidity": 68.4, + "water_total": 38.0, + "average_temperature": 31.3667, + "experience_temperature": 24.6181, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T17:20:07.069972+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.6, + "humidity": 69.6, + "water_total": 81.0, + "average_temperature": 31.2, + "experience_temperature": 27.9057, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T17:30:06.301344+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.8, + "humidity": 69.9, + "water_total": 138.0, + "average_temperature": 31.2333, + "experience_temperature": 26.9276, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T17:40:06.446134+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 71.0, + "water_total": 186.0, + "average_temperature": 31.0667, + "experience_temperature": 27.5167, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T17:50:06.217073+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.8, + "humidity": 72.2, + "water_total": 228.0, + "average_temperature": 30.7, + "experience_temperature": 26.8543, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:00:07.557059+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.9, + "humidity": 72.8, + "water_total": 273.0, + "average_temperature": 30.2667, + "experience_temperature": 26.0052, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:10:06.512029+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.8, + "humidity": 74.4, + "water_total": 307.0, + "average_temperature": 30.0, + "experience_temperature": 26.5943, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:20:06.089703+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.5, + "humidity": 75.0, + "water_total": 338.0, + "average_temperature": 29.7, + "experience_temperature": 28.0214, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:30:08.890416+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 75.3, + "water_total": 376.0, + "average_temperature": 29.7, + "experience_temperature": 27.01, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:40:06.499707+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 75.4, + "water_total": 424.0, + "average_temperature": 29.8, + "experience_temperature": 27.13, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T18:50:07.166612+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.8, + "humidity": 74.6, + "water_total": 469.0, + "average_temperature": 29.7333, + "experience_temperature": 26.3676, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:00:06.397876+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 74.2, + "water_total": 515.0, + "average_temperature": 29.7, + "experience_temperature": 29.4686, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:10:08.167807+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.4, + "humidity": 75.2, + "water_total": 553.0, + "average_temperature": 29.6333, + "experience_temperature": 28.5305, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:20:05.921365+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 76.2, + "water_total": 594.0, + "average_temperature": 29.6667, + "experience_temperature": 29.8352, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:30:07.910020+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 78.3, + "water_total": 632.0, + "average_temperature": 29.7667, + "experience_temperature": 29.8195, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:40:06.737054+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 76.3, + "water_total": 662.0, + "average_temperature": 29.6, + "experience_temperature": 29.7886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T19:50:06.451737+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 77.0, + "water_total": 717.0, + "average_temperature": 29.5667, + "experience_temperature": 29.8952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:00:08.207340+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 77.0, + "water_total": 768.0, + "average_temperature": 29.5, + "experience_temperature": 29.8286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:10:06.721721+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.5, + "water_total": 812.0, + "average_temperature": 29.7, + "experience_temperature": 30.5286, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:20:07.118683+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.6, + "humidity": 78.5, + "water_total": 854.0, + "average_temperature": 29.7667, + "experience_temperature": 28.2524, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:30:06.371875+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.4, + "humidity": 78.1, + "water_total": 903.0, + "average_temperature": 29.7, + "experience_temperature": 29.1771, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:40:06.140903+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 77.3, + "water_total": 943.0, + "average_temperature": 29.6667, + "experience_temperature": 30.591, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T20:50:06.949824+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.6, + "humidity": 79.4, + "water_total": 970.0, + "average_temperature": 29.7667, + "experience_temperature": 28.4324, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:00:07.331094+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.4, + "humidity": 77.6, + "water_total": 1021.0, + "average_temperature": 29.6333, + "experience_temperature": 29.0105, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:10:06.406832+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.7, + "humidity": 78.6, + "water_total": 1085.0, + "average_temperature": 29.7667, + "experience_temperature": 27.7367, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:20:06.844716+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.0, + "water_total": 1123.0, + "average_temperature": 29.6667, + "experience_temperature": 31.131, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:30:06.999631+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 77.7, + "water_total": 1167.0, + "average_temperature": 29.5667, + "experience_temperature": 30.0352, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:40:06.470677+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.4, + "humidity": 77.0, + "water_total": 1212.0, + "average_temperature": 29.7, + "experience_temperature": 28.9571, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T21:50:06.546587+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 78.4, + "water_total": 1256.0, + "average_temperature": 29.6667, + "experience_temperature": 30.2752, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:00:07.695235+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 79.6, + "water_total": 1298.0, + "average_temperature": 29.5333, + "experience_temperature": 30.9176, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:10:07.433678+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 78.6, + "water_total": 1345.0, + "average_temperature": 29.5333, + "experience_temperature": 30.1819, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:20:07.188139+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 81.5, + "water_total": 1377.0, + "average_temperature": 29.5667, + "experience_temperature": 31.331, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:30:07.402114+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 79.7, + "water_total": 1419.0, + "average_temperature": 29.6667, + "experience_temperature": 29.9995, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:40:07.098274+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.0, + "water_total": 1453.0, + "average_temperature": 29.6667, + "experience_temperature": 30.3952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T22:50:07.245618+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.0, + "water_total": 1453.0, + "average_temperature": 29.6667, + "experience_temperature": 30.3952, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:00:07.270735+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.6, + "water_total": 1534.0, + "average_temperature": 29.6333, + "experience_temperature": 30.4819, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:10:08.166091+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.8, + "water_total": 1570.0, + "average_temperature": 29.6, + "experience_temperature": 30.4886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:20:06.866699+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.2, + "humidity": 79.8, + "water_total": 1570.0, + "average_temperature": 29.6, + "experience_temperature": 30.4886, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:30:06.536049+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.3, + "humidity": 79.5, + "water_total": 1614.0, + "average_temperature": 29.1333, + "experience_temperature": 29.4262, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:40:08.834505+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.1, + "water_total": 1627.0, + "average_temperature": 29.0333, + "experience_temperature": 30.5176, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-07T23:50:06.775538+07:00", + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.4, + "water_total": 1641.0, + "average_temperature": 28.9333, + "experience_temperature": 30.4776, + "chill_factor": 5.3571 + }, + { + "timestamp": "2026-06-08T00:00:07.691571+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 79.9, + "water_total": 1653.0, + "average_temperature": 28.8667, + "experience_temperature": 29.8181, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T00:10:06.129068+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.3, + "water_total": 1673.0, + "average_temperature": 29.1667, + "experience_temperature": 30.3981, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T00:20:07.226961+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 81.4, + "water_total": 1740.0, + "average_temperature": 29.6, + "experience_temperature": 31.3657, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T00:30:06.678712+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 78.6, + "water_total": 1797.0, + "average_temperature": 29.3333, + "experience_temperature": 30.539, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T00:40:07.145102+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.0, + "water_total": 1843.0, + "average_temperature": 29.2333, + "experience_temperature": 30.4048, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T00:50:06.550658+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 1884.0, + "average_temperature": 29.0667, + "experience_temperature": 30.2181, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:00:06.798329+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 79.6, + "water_total": 1923.0, + "average_temperature": 29.0, + "experience_temperature": 29.8914, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:10:07.304292+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 79.9, + "water_total": 1963.0, + "average_temperature": 29.0333, + "experience_temperature": 29.4705, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:20:06.459274+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.0, + "water_total": 2008.0, + "average_temperature": 29.3667, + "experience_temperature": 30.3381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:30:07.594290+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 79.4, + "water_total": 2055.0, + "average_temperature": 29.2667, + "experience_temperature": 30.1181, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:40:07.844802+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 79.7, + "water_total": 2089.0, + "average_temperature": 28.9667, + "experience_temperature": 30.3924, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T01:50:06.750876+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.6, + "water_total": 2121.0, + "average_temperature": 29.0333, + "experience_temperature": 30.1248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:00:06.912950+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.1, + "water_total": 2148.0, + "average_temperature": 28.7333, + "experience_temperature": 29.7248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:10:05.394533+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 2172.0, + "average_temperature": 28.6667, + "experience_temperature": 29.8781, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:20:06.197944+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.0, + "water_total": 2197.0, + "average_temperature": 28.6667, + "experience_temperature": 29.8381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:30:06.261556+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 80.5, + "water_total": 2230.0, + "average_temperature": 28.8, + "experience_temperature": 30.3857, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:40:05.895962+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 82.1, + "water_total": 2263.0, + "average_temperature": 28.9, + "experience_temperature": 30.2914, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T02:50:05.388164+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 82.1, + "water_total": 2263.0, + "average_temperature": 28.9, + "experience_temperature": 30.2914, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:00:05.514697+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 80.5, + "water_total": 2329.0, + "average_temperature": 28.9333, + "experience_temperature": 30.519, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:10:07.545910+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.4, + "water_total": 2345.0, + "average_temperature": 28.3333, + "experience_temperature": 29.5848, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:20:05.879100+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 80.3, + "water_total": 2373.0, + "average_temperature": 28.8667, + "experience_temperature": 29.3838, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:30:06.214875+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 82.3, + "water_total": 2409.0, + "average_temperature": 28.5, + "experience_temperature": 29.4171, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:40:05.879178+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 81.6, + "water_total": 2454.0, + "average_temperature": 28.5, + "experience_temperature": 30.3057, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T03:50:05.700862+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.3, + "water_total": 2484.0, + "average_temperature": 28.2333, + "experience_temperature": 29.4648, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:00:05.948860+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 82.4, + "water_total": 2513.0, + "average_temperature": 27.9667, + "experience_temperature": 29.4181, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:10:06.280490+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 2532.0, + "average_temperature": 27.8667, + "experience_temperature": 29.3381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:20:05.578736+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.8, + "water_total": 2544.0, + "average_temperature": 27.8, + "experience_temperature": 29.1314, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:30:06.001004+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 2558.0, + "average_temperature": 28.1333, + "experience_temperature": 30.6933, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:40:06.058448+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 2558.0, + "average_temperature": 28.1333, + "experience_temperature": 30.6933, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T04:50:05.461091+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 79.9, + "water_total": 2584.0, + "average_temperature": 28.0333, + "experience_temperature": 28.4705, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:00:05.443642+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 2597.0, + "average_temperature": 28.5, + "experience_temperature": 31.12, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:10:06.966670+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 82.5, + "water_total": 2616.0, + "average_temperature": 27.9333, + "experience_temperature": 29.919, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:20:05.892704+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.1, + "water_total": 2676.0, + "average_temperature": 28.2333, + "experience_temperature": 29.4248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:30:05.585208+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 79.9, + "water_total": 2742.0, + "average_temperature": 28.2, + "experience_temperature": 29.1514, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:40:06.105988+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 81.3, + "water_total": 2775.0, + "average_temperature": 28.1, + "experience_temperature": 28.8171, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T05:50:05.884042+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.1, + "water_total": 2813.0, + "average_temperature": 27.6, + "experience_temperature": 28.7914, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:00:05.342917+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.0, + "humidity": 80.5, + "water_total": 2859.0, + "average_temperature": 28.2667, + "experience_temperature": 30.3667, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:10:05.980947+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 79.5, + "water_total": 2906.0, + "average_temperature": 27.6333, + "experience_temperature": 28.5048, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:20:05.901689+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.8, + "water_total": 2940.0, + "average_temperature": 28.1333, + "experience_temperature": 29.4648, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:30:06.131397+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.1, + "water_total": 2967.0, + "average_temperature": 28.0333, + "experience_temperature": 29.0248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:40:06.277017+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 80.2, + "water_total": 3017.0, + "average_temperature": 28.3, + "experience_temperature": 28.7971, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T06:50:07.525594+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 80.2, + "water_total": 3078.0, + "average_temperature": 28.5, + "experience_temperature": 28.9971, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:00:11.182554+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 81.1, + "water_total": 3116.0, + "average_temperature": 28.6333, + "experience_temperature": 29.8248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:10:06.660030+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.7, + "water_total": 3155.0, + "average_temperature": 28.3667, + "experience_temperature": 29.4781, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:20:06.928706+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 80.0, + "water_total": 3205.0, + "average_temperature": 28.2667, + "experience_temperature": 29.2381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:30:06.144180+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 80.0, + "water_total": 3245.0, + "average_temperature": 28.6, + "experience_temperature": 29.0571, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:40:06.237788+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 81.2, + "water_total": 3299.0, + "average_temperature": 28.6, + "experience_temperature": 29.2971, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T07:50:07.407071+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 78.2, + "water_total": 3346.0, + "average_temperature": 28.4667, + "experience_temperature": 29.0781, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:00:09.774709+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 78.2, + "water_total": 3346.0, + "average_temperature": 28.4667, + "experience_temperature": 29.0781, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:10:07.637803+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 79.6, + "water_total": 3383.0, + "average_temperature": 28.7667, + "experience_temperature": 27.0867, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:20:06.983627+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 77.3, + "water_total": 3425.0, + "average_temperature": 29.0333, + "experience_temperature": 26.379, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:30:07.834252+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 75.1, + "water_total": 3533.0, + "average_temperature": 29.9667, + "experience_temperature": 26.8724, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:40:07.703248+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 74.1, + "water_total": 3580.0, + "average_temperature": 30.1333, + "experience_temperature": 26.839, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T08:50:06.173122+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 74.1, + "water_total": 3580.0, + "average_temperature": 30.1333, + "experience_temperature": 26.839, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:00:06.281615+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 71.4, + "water_total": 3629.0, + "average_temperature": 30.6333, + "experience_temperature": 27.3133, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:10:06.802516+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 71.8, + "water_total": 3729.0, + "average_temperature": 31.0667, + "experience_temperature": 28.341, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:20:06.425862+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.5, + "humidity": 71.0, + "water_total": 3785.0, + "average_temperature": 31.1, + "experience_temperature": 28.7286, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:30:05.599167+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.3, + "humidity": 67.8, + "water_total": 3838.0, + "average_temperature": 31.1667, + "experience_temperature": 24.041, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:40:06.007595+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.5, + "humidity": 68.0, + "water_total": 3884.0, + "average_temperature": 31.1333, + "experience_temperature": 23.019, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T09:50:06.179311+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.2, + "humidity": 66.6, + "water_total": 3931.0, + "average_temperature": 31.5, + "experience_temperature": 24.6486, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:00:08.260158+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.1, + "humidity": 64.6, + "water_total": 3973.0, + "average_temperature": 31.9333, + "experience_temperature": 25.1962, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:10:06.197345+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.8, + "humidity": 66.6, + "water_total": 4013.0, + "average_temperature": 32.1333, + "experience_temperature": 22.1962, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:20:06.439496+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.6, + "humidity": 65.8, + "water_total": 4058.0, + "average_temperature": 32.2667, + "experience_temperature": 23.1981, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:30:07.588357+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.5, + "humidity": 66.1, + "water_total": 4100.0, + "average_temperature": 32.3667, + "experience_temperature": 23.8724, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:40:07.847572+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.6, + "humidity": 64.5, + "water_total": 4156.0, + "average_temperature": 32.4333, + "experience_temperature": 23.1048, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T10:50:07.021683+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.5, + "humidity": 64.1, + "water_total": 4218.0, + "average_temperature": 32.5333, + "experience_temperature": 23.639, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:00:07.187235+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.8, + "humidity": 64.2, + "water_total": 4270.0, + "average_temperature": 32.9333, + "experience_temperature": 22.5162, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:10:06.693901+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.2, + "humidity": 63.1, + "water_total": 4332.0, + "average_temperature": 33.2, + "experience_temperature": 20.5057, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:20:06.424639+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.2, + "humidity": 64.0, + "water_total": 4377.0, + "average_temperature": 33.1333, + "experience_temperature": 20.619, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:30:06.545289+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 61.5, + "water_total": 4431.0, + "average_temperature": 33.2333, + "experience_temperature": 19.7048, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:40:07.137720+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 60.3, + "water_total": 4475.0, + "average_temperature": 33.3, + "experience_temperature": 19.5314, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T11:50:07.257827+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.6, + "humidity": 60.3, + "water_total": 4526.0, + "average_temperature": 33.8667, + "experience_temperature": 23.6981, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:00:06.293507+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 60.0, + "water_total": 4585.0, + "average_temperature": 33.7333, + "experience_temperature": 21.9619, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:10:08.489372+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 59.5, + "water_total": 4630.0, + "average_temperature": 33.5, + "experience_temperature": 19.5714, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:20:06.968271+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 60.5, + "water_total": 4683.0, + "average_temperature": 33.7667, + "experience_temperature": 20.0381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:30:06.736027+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 58.4, + "water_total": 4731.0, + "average_temperature": 33.9667, + "experience_temperature": 21.8752, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:40:05.739434+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.1, + "humidity": 60.1, + "water_total": 4782.0, + "average_temperature": 33.7667, + "experience_temperature": 20.9867, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T12:50:07.204262+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 58.6, + "water_total": 4831.0, + "average_temperature": 33.8333, + "experience_temperature": 19.7248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:00:06.759482+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.1, + "humidity": 59.3, + "water_total": 4894.0, + "average_temperature": 33.9667, + "experience_temperature": 21.0267, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:10:06.859420+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 59.1, + "water_total": 4945.0, + "average_temperature": 33.6667, + "experience_temperature": 21.7152, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:20:08.195722+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.0, + "humidity": 57.9, + "water_total": 4989.0, + "average_temperature": 33.4333, + "experience_temperature": 20.7276, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:30:09.712872+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 57.8, + "water_total": 5035.0, + "average_temperature": 33.7, + "experience_temperature": 19.4314, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:40:10.267686+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 59.2, + "water_total": 5089.0, + "average_temperature": 33.9667, + "experience_temperature": 22.0352, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T13:50:07.359493+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 58.3, + "water_total": 5133.0, + "average_temperature": 33.5333, + "experience_temperature": 21.4219, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T14:10:06.592598+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.2, + "humidity": 58.5, + "water_total": 5237.0, + "average_temperature": 33.9333, + "experience_temperature": 20.319, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T14:20:07.765990+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.3, + "humidity": 59.2, + "water_total": 5288.0, + "average_temperature": 33.8667, + "experience_temperature": 19.8781, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T14:30:07.800935+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.1, + "humidity": 59.6, + "water_total": 5345.0, + "average_temperature": 33.5333, + "experience_temperature": 20.6533, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T14:40:06.875220+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.1, + "humidity": 60.3, + "water_total": 5385.0, + "average_temperature": 33.5333, + "experience_temperature": 20.7933, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T14:50:07.619968+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.8, + "humidity": 60.4, + "water_total": 5427.0, + "average_temperature": 33.6333, + "experience_temperature": 22.4562, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T15:10:06.551217+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.0, + "humidity": 66.4, + "water_total": 5554.0, + "average_temperature": 33.5667, + "experience_temperature": 22.561, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T15:20:07.267035+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.0, + "humidity": 67.6, + "water_total": 5607.0, + "average_temperature": 33.0333, + "experience_temperature": 22.2676, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T15:30:07.412637+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 2.0, + "humidity": 67.6, + "water_total": 5607.0, + "average_temperature": 33.0333, + "experience_temperature": 22.2676, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T15:40:07.511195+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 5705.0, + "average_temperature": 32.9667, + "experience_temperature": 22.7352, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T15:50:06.942263+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.9, + "humidity": 66.6, + "water_total": 5742.0, + "average_temperature": 32.9667, + "experience_temperature": 22.5152, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T16:10:10.645297+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.8, + "humidity": 67.2, + "water_total": 5853.0, + "average_temperature": 32.4667, + "experience_temperature": 22.6495, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T16:20:06.598101+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.8, + "humidity": 66.8, + "water_total": 5899.0, + "average_temperature": 32.2333, + "experience_temperature": 22.3362, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T16:30:06.604120+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.6, + "humidity": 67.1, + "water_total": 5947.0, + "average_temperature": 32.0333, + "experience_temperature": 23.2248, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T16:40:06.690989+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.4, + "humidity": 66.7, + "water_total": 5997.0, + "average_temperature": 31.9, + "experience_temperature": 24.04, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T16:50:08.111664+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.2, + "humidity": 66.3, + "water_total": 6056.0, + "average_temperature": 31.7333, + "experience_temperature": 24.8219, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T17:10:07.423418+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.4, + "humidity": 66.3, + "water_total": 40.0, + "average_temperature": 31.1333, + "experience_temperature": 23.1933, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T17:20:06.778308+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.9, + "humidity": 67.2, + "water_total": 88.0, + "average_temperature": 31.0333, + "experience_temperature": 25.8448, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T17:30:06.373665+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 1.2, + "humidity": 67.5, + "water_total": 153.0, + "average_temperature": 31.0667, + "experience_temperature": 24.3952, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T17:40:07.792164+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 67.3, + "water_total": 214.0, + "average_temperature": 30.8333, + "experience_temperature": 27.2076, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T17:50:08.264764+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 68.8, + "water_total": 269.0, + "average_temperature": 30.6, + "experience_temperature": 26.2457, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:00:08.066337+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 70.7, + "water_total": 324.0, + "average_temperature": 30.4333, + "experience_temperature": 27.4876, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:10:07.866615+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 70.4, + "water_total": 376.0, + "average_temperature": 30.3333, + "experience_temperature": 26.8133, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:20:06.582627+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 71.4, + "water_total": 425.0, + "average_temperature": 30.3, + "experience_temperature": 26.98, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:30:08.581079+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 71.9, + "water_total": 473.0, + "average_temperature": 30.0667, + "experience_temperature": 26.8467, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:40:08.078277+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 72.9, + "water_total": 520.0, + "average_temperature": 30.1333, + "experience_temperature": 27.1133, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T18:50:07.398650+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 74.1, + "water_total": 577.0, + "average_temperature": 30.1667, + "experience_temperature": 27.3867, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:00:08.931975+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 75.0, + "water_total": 625.0, + "average_temperature": 29.9, + "experience_temperature": 27.3, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:10:06.373297+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 76.1, + "water_total": 672.0, + "average_temperature": 29.8, + "experience_temperature": 27.9343, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:20:06.417056+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.5, + "humidity": 77.7, + "water_total": 719.0, + "average_temperature": 29.6667, + "experience_temperature": 28.6352, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:30:06.610272+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 77.5, + "water_total": 771.0, + "average_temperature": 29.5667, + "experience_temperature": 27.981, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:40:06.456813+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.4, + "humidity": 79.2, + "water_total": 820.0, + "average_temperature": 29.3667, + "experience_temperature": 29.1495, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T19:50:07.000374+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 77.4, + "water_total": 869.0, + "average_temperature": 29.1667, + "experience_temperature": 27.561, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:00:07.801736+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 77.5, + "water_total": 923.0, + "average_temperature": 29.2667, + "experience_temperature": 27.1667, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:10:07.707160+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 77.0, + "water_total": 968.0, + "average_temperature": 29.4667, + "experience_temperature": 27.2667, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:20:06.125261+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 78.1, + "water_total": 1016.0, + "average_temperature": 29.3, + "experience_temperature": 27.8343, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:30:06.450445+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 76.5, + "water_total": 1060.0, + "average_temperature": 29.1333, + "experience_temperature": 26.8333, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:40:07.199277+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.9, + "humidity": 78.0, + "water_total": 1094.0, + "average_temperature": 28.8667, + "experience_temperature": 25.8381, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T20:50:07.076272+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 78.0, + "water_total": 1149.0, + "average_temperature": 29.0333, + "experience_temperature": 26.519, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:00:06.713683+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 78.6, + "water_total": 1213.0, + "average_temperature": 28.6333, + "experience_temperature": 27.2676, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:10:07.220262+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 79.4, + "water_total": 1274.0, + "average_temperature": 28.3, + "experience_temperature": 26.58, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:20:06.732757+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 80.1, + "water_total": 1325.0, + "average_temperature": 28.3667, + "experience_temperature": 26.2724, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:30:07.092110+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 81.3, + "water_total": 1363.0, + "average_temperature": 28.2333, + "experience_temperature": 26.8933, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:40:06.940040+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 81.9, + "water_total": 1405.0, + "average_temperature": 28.1333, + "experience_temperature": 26.399, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T21:50:07.728800+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 82.0, + "water_total": 1444.0, + "average_temperature": 28.2333, + "experience_temperature": 26.519, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:00:07.554411+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.8, + "humidity": 82.3, + "water_total": 1492.0, + "average_temperature": 28.3, + "experience_temperature": 26.6457, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:10:06.708140+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 82.2, + "water_total": 1536.0, + "average_temperature": 28.1, + "experience_temperature": 26.94, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:20:06.894000+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 80.9, + "water_total": 1576.0, + "average_temperature": 28.0333, + "experience_temperature": 27.1276, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:30:07.337684+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.7, + "humidity": 81.5, + "water_total": 1634.0, + "average_temperature": 28.2667, + "experience_temperature": 26.9667, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:40:05.659135+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.4, + "humidity": 80.9, + "water_total": 1692.0, + "average_temperature": 27.9667, + "experience_temperature": 28.0895, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T22:50:07.211471+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.6, + "humidity": 81.4, + "water_total": 1739.0, + "average_temperature": 28.0, + "experience_temperature": 27.1943, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:00:05.890490+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.1, + "humidity": 80.2, + "water_total": 1758.0, + "average_temperature": 27.8667, + "experience_temperature": 29.3924, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:10:05.804453+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.3, + "humidity": 82.0, + "water_total": 1775.0, + "average_temperature": 28.0333, + "experience_temperature": 28.8905, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:20:05.982799+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.5, + "humidity": 81.5, + "water_total": 1786.0, + "average_temperature": 28.0333, + "experience_temperature": 27.7619, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:30:06.328526+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.2, + "humidity": 82.8, + "water_total": 1803.0, + "average_temperature": 27.9667, + "experience_temperature": 29.4981, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:40:05.854118+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.4, + "humidity": 80.4, + "water_total": 1817.0, + "average_temperature": 27.8667, + "experience_temperature": 27.8895, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-08T23:50:05.567573+07:00", + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.4, + "humidity": 82.6, + "water_total": 1831.0, + "average_temperature": 28.0333, + "experience_temperature": 28.4962, + "chill_factor": 5.1429 + }, + { + "timestamp": "2026-06-09T00:00:07.231253+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 83.4, + "water_total": 1847.0, + "average_temperature": 28.0667, + "experience_temperature": 27.7895, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T00:10:07.328154+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.3, + "humidity": 81.4, + "water_total": 1865.0, + "average_temperature": 27.8333, + "experience_temperature": 28.6348, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T00:20:06.060375+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 83.2, + "water_total": 1959.0, + "average_temperature": 28.0, + "experience_temperature": 27.6829, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T00:30:06.240589+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.4, + "humidity": 81.8, + "water_total": 2015.0, + "average_temperature": 27.8667, + "experience_temperature": 28.2552, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T00:40:05.700562+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 81.5, + "water_total": 2077.0, + "average_temperature": 27.8333, + "experience_temperature": 29.6405, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T00:50:06.053146+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 83.0, + "water_total": 2133.0, + "average_temperature": 27.9667, + "experience_temperature": 27.6095, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:00:05.926452+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 82.0, + "water_total": 2197.0, + "average_temperature": 27.9667, + "experience_temperature": 26.4238, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:10:06.022319+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 2256.0, + "average_temperature": 27.9, + "experience_temperature": 29.4143, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:20:06.111586+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 79.7, + "water_total": 2307.0, + "average_temperature": 27.5667, + "experience_temperature": 28.521, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:30:05.947225+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 82.3, + "water_total": 2339.0, + "average_temperature": 27.9333, + "experience_temperature": 29.4076, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:40:05.916125+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.3, + "water_total": 2385.0, + "average_temperature": 27.8333, + "experience_temperature": 27.1362, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T01:50:05.952970+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.5, + "water_total": 2435.0, + "average_temperature": 27.8333, + "experience_temperature": 29.1476, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:00:06.762754+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.8, + "water_total": 2492.0, + "average_temperature": 27.8333, + "experience_temperature": 29.2076, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:10:07.200652+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 2521.0, + "average_temperature": 27.8667, + "experience_temperature": 29.061, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:20:06.322630+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 79.8, + "water_total": 2569.0, + "average_temperature": 27.7667, + "experience_temperature": 26.2767, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:30:05.690268+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.0, + "humidity": 82.2, + "water_total": 2602.0, + "average_temperature": 27.9333, + "experience_temperature": 30.3733, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:40:06.504857+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.1, + "water_total": 2629.0, + "average_temperature": 27.9333, + "experience_temperature": 27.1962, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T02:50:05.403974+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.3, + "humidity": 82.0, + "water_total": 2705.0, + "average_temperature": 27.9, + "experience_temperature": 28.8214, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:00:05.522252+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.0, + "humidity": 82.8, + "water_total": 2742.0, + "average_temperature": 27.7667, + "experience_temperature": 30.3267, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:10:05.716818+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 82.5, + "water_total": 2776.0, + "average_temperature": 27.8, + "experience_temperature": 29.3143, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:20:06.981027+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 82.8, + "water_total": 2822.0, + "average_temperature": 27.9667, + "experience_temperature": 27.5695, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:30:06.564629+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 82.4, + "water_total": 2855.0, + "average_temperature": 27.6667, + "experience_temperature": 29.161, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:40:06.607981+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.1, + "water_total": 2896.0, + "average_temperature": 27.6333, + "experience_temperature": 28.8676, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T03:50:05.773576+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 82.0, + "water_total": 2930.0, + "average_temperature": 27.8333, + "experience_temperature": 29.2476, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:00:05.931306+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 82.2, + "water_total": 2965.0, + "average_temperature": 27.9, + "experience_temperature": 26.3971, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:10:06.015932+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.7, + "water_total": 3008.0, + "average_temperature": 27.4333, + "experience_temperature": 28.7876, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:20:05.847724+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 81.2, + "water_total": 3022.0, + "average_temperature": 27.5667, + "experience_temperature": 29.3138, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:30:05.764818+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 80.3, + "water_total": 3039.0, + "average_temperature": 27.5333, + "experience_temperature": 28.6076, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:40:05.600244+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.6, + "water_total": 3052.0, + "average_temperature": 27.3, + "experience_temperature": 28.6343, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T04:50:06.094300+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.9, + "water_total": 3065.0, + "average_temperature": 27.3667, + "experience_temperature": 28.761, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:00:07.684576+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 82.6, + "water_total": 3082.0, + "average_temperature": 27.8333, + "experience_temperature": 29.8605, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:10:07.904663+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 82.4, + "water_total": 3098.0, + "average_temperature": 28.3333, + "experience_temperature": 27.3633, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:20:05.612294+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 83.0, + "water_total": 3173.0, + "average_temperature": 27.7333, + "experience_temperature": 29.8405, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:30:05.904439+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.2, + "water_total": 3243.0, + "average_temperature": 27.7667, + "experience_temperature": 29.021, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:40:06.759757+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.0, + "water_total": 3286.0, + "average_temperature": 27.5667, + "experience_temperature": 28.781, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T05:50:06.503798+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.5, + "humidity": 83.2, + "water_total": 3338.0, + "average_temperature": 27.9667, + "experience_temperature": 28.1424, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:00:05.906287+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 80.9, + "water_total": 3395.0, + "average_temperature": 27.8333, + "experience_temperature": 29.0276, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:10:05.860964+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.4, + "water_total": 3440.0, + "average_temperature": 27.4667, + "experience_temperature": 28.761, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:20:06.583058+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 82.4, + "water_total": 3488.0, + "average_temperature": 27.6, + "experience_temperature": 29.5871, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:30:06.278735+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 82.2, + "water_total": 3535.0, + "average_temperature": 27.8, + "experience_temperature": 29.7471, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:40:06.225605+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 80.7, + "water_total": 3597.0, + "average_temperature": 27.7, + "experience_temperature": 29.3471, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T06:50:05.877343+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.1, + "humidity": 80.7, + "water_total": 3597.0, + "average_temperature": 27.7, + "experience_temperature": 29.3471, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:00:05.632408+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.3, + "humidity": 81.4, + "water_total": 3662.0, + "average_temperature": 27.7333, + "experience_temperature": 28.5348, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:10:07.076073+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.2, + "humidity": 81.7, + "water_total": 3710.0, + "average_temperature": 27.6333, + "experience_temperature": 28.9876, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:20:06.289359+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 81.7, + "water_total": 3763.0, + "average_temperature": 27.9, + "experience_temperature": 26.2971, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:30:05.566206+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.3, + "humidity": 82.3, + "water_total": 3821.0, + "average_temperature": 27.7667, + "experience_temperature": 28.7481, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:40:07.737540+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 80.7, + "water_total": 3879.0, + "average_temperature": 27.8333, + "experience_temperature": 27.0162, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T07:50:06.181167+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.3, + "humidity": 82.5, + "water_total": 3925.0, + "average_temperature": 27.8333, + "experience_temperature": 28.8548, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:00:11.128444+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 83.4, + "water_total": 3966.0, + "average_temperature": 28.0333, + "experience_temperature": 27.7562, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:10:05.784448+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.1, + "water_total": 4013.0, + "average_temperature": 28.0333, + "experience_temperature": 27.2962, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:20:05.742421+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.1, + "water_total": 4013.0, + "average_temperature": 28.0333, + "experience_temperature": 27.2962, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:30:05.989719+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 81.7, + "water_total": 4069.0, + "average_temperature": 28.1667, + "experience_temperature": 27.0567, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:40:06.508410+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 80.3, + "water_total": 4191.0, + "average_temperature": 29.4667, + "experience_temperature": 27.5838, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T08:50:05.300174+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 81.2, + "water_total": 4251.0, + "average_temperature": 29.4333, + "experience_temperature": 27.7305, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:00:06.029607+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 79.5, + "water_total": 4323.0, + "average_temperature": 29.7, + "experience_temperature": 28.15, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:10:05.552678+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 78.9, + "water_total": 4385.0, + "average_temperature": 30.2, + "experience_temperature": 28.53, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:20:05.905753+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 76.8, + "water_total": 4433.0, + "average_temperature": 29.9, + "experience_temperature": 24.8529, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:30:06.066013+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 76.1, + "water_total": 4489.0, + "average_temperature": 30.4333, + "experience_temperature": 25.739, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:40:05.898315+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 73.0, + "water_total": 4547.0, + "average_temperature": 30.8333, + "experience_temperature": 25.519, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T09:50:05.866947+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 72.2, + "water_total": 4593.0, + "average_temperature": 31.1667, + "experience_temperature": 25.1995, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:00:07.783385+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 70.3, + "water_total": 4644.0, + "average_temperature": 31.2, + "experience_temperature": 25.3457, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:10:05.733806+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.5, + "humidity": 71.3, + "water_total": 4692.0, + "average_temperature": 31.5333, + "experience_temperature": 24.4005, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:20:07.503915+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 69.6, + "water_total": 4741.0, + "average_temperature": 31.8, + "experience_temperature": 22.3557, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:30:06.580380+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.7, + "humidity": 69.5, + "water_total": 4789.0, + "average_temperature": 32.0, + "experience_temperature": 23.5214, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:40:07.245467+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 4839.0, + "average_temperature": 31.9333, + "experience_temperature": 22.189, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T10:50:06.611896+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 66.8, + "water_total": 4886.0, + "average_temperature": 32.1333, + "experience_temperature": 22.129, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:00:06.131457+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.8, + "humidity": 67.4, + "water_total": 4947.0, + "average_temperature": 32.3, + "experience_temperature": 22.9086, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:10:06.825423+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 66.6, + "water_total": 5004.0, + "average_temperature": 32.4333, + "experience_temperature": 20.9105, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:20:06.144956+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.7, + "humidity": 66.7, + "water_total": 5056.0, + "average_temperature": 32.2333, + "experience_temperature": 23.1948, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:30:05.990634+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.7, + "humidity": 66.0, + "water_total": 5104.0, + "average_temperature": 32.0667, + "experience_temperature": 22.8881, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:40:06.356120+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.1, + "humidity": 65.9, + "water_total": 5154.0, + "average_temperature": 32.6333, + "experience_temperature": 21.4633, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T11:50:06.097938+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.1, + "humidity": 63.8, + "water_total": 5201.0, + "average_temperature": 32.6667, + "experience_temperature": 21.0767, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:00:05.802045+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.0, + "humidity": 65.4, + "water_total": 5251.0, + "average_temperature": 32.7667, + "experience_temperature": 21.9895, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:10:05.995905+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.3, + "humidity": 65.2, + "water_total": 5309.0, + "average_temperature": 32.9667, + "experience_temperature": 20.671, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:20:07.266075+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.1, + "humidity": 65.1, + "water_total": 5354.0, + "average_temperature": 33.1667, + "experience_temperature": 21.8367, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:30:06.118471+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.0, + "humidity": 65.4, + "water_total": 5415.0, + "average_temperature": 33.2, + "experience_temperature": 22.4229, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:40:05.900787+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.0, + "humidity": 64.9, + "water_total": 5468.0, + "average_temperature": 33.0, + "experience_temperature": 22.1229, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T12:50:06.137588+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.8, + "humidity": 63.7, + "water_total": 5519.0, + "average_temperature": 32.9667, + "experience_temperature": 22.8352, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:00:06.239681+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 64.3, + "water_total": 5575.0, + "average_temperature": 33.1667, + "experience_temperature": 22.6624, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:10:06.925992+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.3, + "humidity": 65.0, + "water_total": 5627.0, + "average_temperature": 33.2667, + "experience_temperature": 20.931, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:20:05.599752+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.4, + "humidity": 63.9, + "water_total": 5675.0, + "average_temperature": 32.9, + "experience_temperature": 19.8514, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:30:05.784502+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 65.6, + "water_total": 5725.0, + "average_temperature": 33.0667, + "experience_temperature": 21.3438, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:40:07.010128+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.0, + "humidity": 64.9, + "water_total": 5773.0, + "average_temperature": 32.9333, + "experience_temperature": 22.0562, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T13:50:09.697265+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 65.0, + "water_total": 5829.0, + "average_temperature": 33.1667, + "experience_temperature": 22.8024, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T14:10:08.124285+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 64.2, + "water_total": 5923.0, + "average_temperature": 33.2333, + "experience_temperature": 21.2305, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T14:20:06.076793+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.4, + "humidity": 64.9, + "water_total": 5970.0, + "average_temperature": 33.1667, + "experience_temperature": 20.3181, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T14:30:07.958416+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 65.0, + "water_total": 6001.0, + "average_temperature": 33.1333, + "experience_temperature": 22.769, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T14:40:05.793307+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 65.0, + "water_total": 6001.0, + "average_temperature": 33.1333, + "experience_temperature": 22.769, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T14:50:07.468726+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 65.3, + "water_total": 6099.0, + "average_temperature": 33.1667, + "experience_temperature": 22.8624, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T15:10:07.537589+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 63.7, + "water_total": 6224.0, + "average_temperature": 33.0333, + "experience_temperature": 20.9305, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T15:20:08.412365+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.3, + "humidity": 64.7, + "water_total": 6277.0, + "average_temperature": 32.8667, + "experience_temperature": 20.471, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T15:30:06.648183+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.1, + "humidity": 66.2, + "water_total": 6322.0, + "average_temperature": 32.8667, + "experience_temperature": 21.7567, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T15:40:07.149152+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.4, + "humidity": 65.2, + "water_total": 6379.0, + "average_temperature": 32.7, + "experience_temperature": 19.9114, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T15:50:06.345157+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 66.9, + "water_total": 6426.0, + "average_temperature": 32.6333, + "experience_temperature": 21.1705, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T16:10:07.335893+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 2.2, + "humidity": 66.2, + "water_total": 6548.0, + "average_temperature": 32.3, + "experience_temperature": 20.6971, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T16:20:06.286602+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.7, + "humidity": 67.9, + "water_total": 6593.0, + "average_temperature": 32.1333, + "experience_temperature": 23.3348, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T16:30:06.306464+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.8, + "humidity": 70.2, + "water_total": 6653.0, + "average_temperature": 32.0, + "experience_temperature": 23.1686, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T16:40:05.906340+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.8, + "humidity": 72.5, + "water_total": 6709.0, + "average_temperature": 31.6, + "experience_temperature": 23.2286, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T16:50:05.839744+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.9, + "humidity": 72.7, + "water_total": 6756.0, + "average_temperature": 31.2667, + "experience_temperature": 22.4424, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T17:10:06.559266+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 75.0, + "water_total": 52.0, + "average_temperature": 31.0667, + "experience_temperature": 26.1524, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T17:20:06.259571+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 75.7, + "water_total": 107.0, + "average_temperature": 30.5333, + "experience_temperature": 25.2662, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T17:30:07.256322+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 77.2, + "water_total": 146.0, + "average_temperature": 30.2333, + "experience_temperature": 25.759, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T17:40:06.013392+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 77.6, + "water_total": 178.0, + "average_temperature": 30.0, + "experience_temperature": 25.6057, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T17:50:06.443747+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 77.9, + "water_total": 241.0, + "average_temperature": 29.9, + "experience_temperature": 25.0729, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:00:06.645739+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 78.0, + "water_total": 285.0, + "average_temperature": 29.7, + "experience_temperature": 24.8929, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:10:06.680902+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 79.0, + "water_total": 320.0, + "average_temperature": 29.4667, + "experience_temperature": 24.8595, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:20:08.675948+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.2, + "humidity": 80.0, + "water_total": 368.0, + "average_temperature": 29.3333, + "experience_temperature": 25.419, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:30:07.668483+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 79.1, + "water_total": 408.0, + "average_temperature": 29.2667, + "experience_temperature": 24.6795, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:40:06.323615+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 79.2, + "water_total": 460.0, + "average_temperature": 29.2, + "experience_temperature": 27.59, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T18:50:06.925245+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.4, + "humidity": 78.8, + "water_total": 511.0, + "average_temperature": 29.2667, + "experience_temperature": 24.1267, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:00:07.431689+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.9, + "humidity": 79.8, + "water_total": 558.0, + "average_temperature": 29.3, + "experience_temperature": 26.8243, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:10:07.238595+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.5, + "humidity": 79.5, + "water_total": 611.0, + "average_temperature": 29.2333, + "experience_temperature": 28.669, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:20:06.989685+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 78.0, + "water_total": 681.0, + "average_temperature": 29.1, + "experience_temperature": 27.25, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:30:07.086235+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 78.2, + "water_total": 731.0, + "average_temperature": 29.1333, + "experience_temperature": 27.8162, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:40:07.113616+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 77.7, + "water_total": 788.0, + "average_temperature": 29.0, + "experience_temperature": 27.5829, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T19:50:06.975248+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 77.7, + "water_total": 788.0, + "average_temperature": 29.0, + "experience_temperature": 27.5829, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:00:06.025500+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.5, + "water_total": 897.0, + "average_temperature": 28.6333, + "experience_temperature": 27.9762, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:10:05.760683+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 80.4, + "water_total": 938.0, + "average_temperature": 28.5667, + "experience_temperature": 27.6895, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:20:05.939091+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 79.5, + "water_total": 990.0, + "average_temperature": 28.6333, + "experience_temperature": 26.5905, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:30:05.473950+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 1046.0, + "average_temperature": 28.7333, + "experience_temperature": 27.8033, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:40:06.353309+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.3, + "humidity": 82.1, + "water_total": 1103.0, + "average_temperature": 28.8333, + "experience_temperature": 24.8462, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T20:50:06.162031+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 80.8, + "water_total": 1152.0, + "average_temperature": 28.6667, + "experience_temperature": 27.8695, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:00:06.587021+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 1.0, + "humidity": 81.6, + "water_total": 1210.0, + "average_temperature": 28.6667, + "experience_temperature": 26.0581, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:10:08.690408+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 81.4, + "water_total": 1255.0, + "average_temperature": 28.6333, + "experience_temperature": 26.9705, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:20:06.576091+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 81.1, + "water_total": 1302.0, + "average_temperature": 28.6333, + "experience_temperature": 27.4033, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:30:08.329262+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 82.7, + "water_total": 1350.0, + "average_temperature": 28.6, + "experience_temperature": 27.69, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:40:06.946142+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 81.8, + "water_total": 1408.0, + "average_temperature": 28.6, + "experience_temperature": 28.0029, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T21:50:07.120128+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 1454.0, + "average_temperature": 28.7, + "experience_temperature": 27.77, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:00:06.531509+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 81.2, + "water_total": 1518.0, + "average_temperature": 28.6667, + "experience_temperature": 27.4567, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:10:07.753988+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 82.1, + "water_total": 1552.0, + "average_temperature": 28.2667, + "experience_temperature": 27.2367, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:20:06.353221+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 1583.0, + "average_temperature": 27.8, + "experience_temperature": 27.29, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:30:06.720034+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 84.2, + "water_total": 1647.0, + "average_temperature": 28.1333, + "experience_temperature": 27.5233, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:40:09.441365+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 82.6, + "water_total": 1707.0, + "average_temperature": 28.1, + "experience_temperature": 26.6771, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T22:50:06.449436+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.8, + "humidity": 83.4, + "water_total": 1742.0, + "average_temperature": 28.3333, + "experience_temperature": 27.0705, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:00:06.714954+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 81.4, + "water_total": 1784.0, + "average_temperature": 28.4667, + "experience_temperature": 27.2967, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:10:07.098364+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 82.8, + "water_total": 1819.0, + "average_temperature": 28.1333, + "experience_temperature": 27.7362, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:20:06.590522+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 83.1, + "water_total": 1859.0, + "average_temperature": 27.8, + "experience_temperature": 26.97, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:30:06.507834+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 84.4, + "water_total": 1871.0, + "average_temperature": 27.7333, + "experience_temperature": 27.6562, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:40:06.859619+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 1885.0, + "average_temperature": 27.8333, + "experience_temperature": 27.9362, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-09T23:50:06.805276+07:00", + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 84.1, + "water_total": 1898.0, + "average_temperature": 27.8, + "experience_temperature": 27.17, + "chill_factor": 4.9286 + }, + { + "timestamp": "2026-06-10T00:00:06.598756+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.1, + "water_total": 1911.0, + "average_temperature": 27.8, + "experience_temperature": 26.8486, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T00:10:06.222449+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.0, + "humidity": 86.1, + "water_total": 1933.0, + "average_temperature": 28.8333, + "experience_temperature": 27.339, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T00:20:07.356606+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.2, + "water_total": 2034.0, + "average_temperature": 28.4, + "experience_temperature": 27.4686, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T00:30:05.989703+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.4, + "water_total": 2104.0, + "average_temperature": 28.0, + "experience_temperature": 27.38, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T00:40:06.467215+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.9, + "humidity": 84.3, + "water_total": 2149.0, + "average_temperature": 27.7333, + "experience_temperature": 26.3505, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T00:50:07.421675+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 85.0, + "water_total": 2206.0, + "average_temperature": 27.8333, + "experience_temperature": 27.5333, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:00:06.191147+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 2262.0, + "average_temperature": 27.8333, + "experience_temperature": 28.0648, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:10:07.820388+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.8, + "water_total": 2318.0, + "average_temperature": 27.9667, + "experience_temperature": 27.1552, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:20:06.147796+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.5, + "humidity": 84.8, + "water_total": 2372.0, + "average_temperature": 27.7667, + "experience_temperature": 28.3695, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:30:07.617389+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 2422.0, + "average_temperature": 27.8, + "experience_temperature": 27.4, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:40:06.028465+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.4, + "water_total": 2470.0, + "average_temperature": 27.9, + "experience_temperature": 27.7514, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T01:50:06.088297+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.9, + "water_total": 2508.0, + "average_temperature": 27.4667, + "experience_temperature": 27.1467, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:00:06.879739+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 84.0, + "water_total": 2540.0, + "average_temperature": 27.5333, + "experience_temperature": 27.5048, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:10:06.172142+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 2612.0, + "average_temperature": 27.5, + "experience_temperature": 26.72, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:20:07.305052+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 83.5, + "water_total": 2655.0, + "average_temperature": 27.2, + "experience_temperature": 26.1286, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:30:06.189028+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.5, + "water_total": 2687.0, + "average_temperature": 26.7667, + "experience_temperature": 26.1667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:40:06.892291+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.4, + "water_total": 2712.0, + "average_temperature": 26.9667, + "experience_temperature": 26.3467, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T02:50:34.334294+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.8, + "water_total": 2738.0, + "average_temperature": 27.1333, + "experience_temperature": 27.0648, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:00:06.729783+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 82.8, + "water_total": 2775.0, + "average_temperature": 27.0, + "experience_temperature": 25.7886, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:10:06.860882+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 84.6, + "water_total": 2800.0, + "average_temperature": 27.1333, + "experience_temperature": 27.2248, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:20:06.298383+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 85.1, + "water_total": 2838.0, + "average_temperature": 26.7, + "experience_temperature": 26.42, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:30:06.726199+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.9, + "humidity": 83.9, + "water_total": 2869.0, + "average_temperature": 26.9333, + "experience_temperature": 25.4705, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:40:06.407626+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.4, + "water_total": 2925.0, + "average_temperature": 26.9667, + "experience_temperature": 26.0752, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T03:50:06.438268+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 84.6, + "water_total": 2951.0, + "average_temperature": 26.7, + "experience_temperature": 26.7914, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:00:06.429143+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 2976.0, + "average_temperature": 26.6667, + "experience_temperature": 26.3067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:10:06.637399+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 2976.0, + "average_temperature": 26.6667, + "experience_temperature": 26.3067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:20:05.985697+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 3013.0, + "average_temperature": 26.3667, + "experience_temperature": 26.5981, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:30:06.724156+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.8, + "water_total": 3026.0, + "average_temperature": 26.3, + "experience_temperature": 25.76, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:40:06.981152+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 85.8, + "water_total": 3040.0, + "average_temperature": 26.3667, + "experience_temperature": 26.6981, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T04:50:06.948376+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 85.5, + "water_total": 3053.0, + "average_temperature": 26.3667, + "experience_temperature": 25.6952, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:00:06.717480+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.9, + "water_total": 3071.0, + "average_temperature": 26.3667, + "experience_temperature": 26.0467, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:10:06.847644+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 85.0, + "water_total": 3085.0, + "average_temperature": 26.6333, + "experience_temperature": 26.8048, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:20:06.688647+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 84.4, + "water_total": 3166.0, + "average_temperature": 26.9667, + "experience_temperature": 27.0181, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:30:06.319228+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.5, + "water_total": 3223.0, + "average_temperature": 26.3667, + "experience_temperature": 25.4952, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:40:07.627186+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 85.9, + "water_total": 3265.0, + "average_temperature": 26.8667, + "experience_temperature": 26.2752, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T05:50:06.402096+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.7, + "water_total": 3337.0, + "average_temperature": 26.4667, + "experience_temperature": 25.6352, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:00:06.582616+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 85.3, + "water_total": 3378.0, + "average_temperature": 26.2, + "experience_temperature": 25.96, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:10:15.339789+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 79.3, + "water_total": 3378.0, + "average_temperature": 29.7333, + "experience_temperature": 28.2933, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:20:06.570036+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.2, + "water_total": 3483.0, + "average_temperature": 26.5333, + "experience_temperature": 26.0733, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:30:07.378984+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 84.7, + "water_total": 3550.0, + "average_temperature": 26.7, + "experience_temperature": 26.8114, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:40:06.789851+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.5, + "humidity": 85.1, + "water_total": 3609.0, + "average_temperature": 26.7, + "experience_temperature": 27.3629, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T06:50:07.144030+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.8, + "water_total": 3650.0, + "average_temperature": 26.3333, + "experience_temperature": 25.9933, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:00:07.762028+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.5, + "humidity": 86.8, + "water_total": 3687.0, + "average_temperature": 26.6, + "experience_temperature": 27.6029, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:10:07.063926+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.5, + "humidity": 84.1, + "water_total": 3732.0, + "average_temperature": 27.0, + "experience_temperature": 27.4629, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:20:06.758780+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 85.2, + "water_total": 3798.0, + "average_temperature": 27.3333, + "experience_temperature": 27.5448, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:30:05.878412+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.5, + "water_total": 3859.0, + "average_temperature": 27.7, + "experience_temperature": 27.5714, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:40:05.775729+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.5, + "water_total": 3859.0, + "average_temperature": 27.7, + "experience_temperature": 27.5714, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T07:50:05.353525+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.4, + "water_total": 3991.0, + "average_temperature": 28.2667, + "experience_temperature": 28.1181, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:00:05.546081+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 82.4, + "water_total": 4053.0, + "average_temperature": 28.5333, + "experience_temperature": 28.1848, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:10:05.867056+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 82.4, + "water_total": 4053.0, + "average_temperature": 28.5333, + "experience_temperature": 28.1848, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:20:06.165186+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 80.5, + "water_total": 4100.0, + "average_temperature": 28.6667, + "experience_temperature": 25.1095, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:30:06.230724+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 78.7, + "water_total": 4154.0, + "average_temperature": 29.0667, + "experience_temperature": 24.2067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:40:06.018979+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 74.8, + "water_total": 4286.0, + "average_temperature": 30.1, + "experience_temperature": 24.9314, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T08:50:06.214866+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 73.2, + "water_total": 4338.0, + "average_temperature": 30.5, + "experience_temperature": 25.4829, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:00:06.304534+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 73.2, + "water_total": 4338.0, + "average_temperature": 30.5, + "experience_temperature": 25.4829, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:10:08.581524+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 70.2, + "water_total": 4459.0, + "average_temperature": 30.7333, + "experience_temperature": 24.6448, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:20:06.269606+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 71.7, + "water_total": 4526.0, + "average_temperature": 31.0333, + "experience_temperature": 24.7733, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:30:05.867454+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.5, + "humidity": 69.6, + "water_total": 4588.0, + "average_temperature": 31.0, + "experience_temperature": 23.8486, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:40:06.678344+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 69.9, + "water_total": 4643.0, + "average_temperature": 31.1667, + "experience_temperature": 22.1895, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T09:50:06.131579+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 69.9, + "water_total": 4643.0, + "average_temperature": 31.1667, + "experience_temperature": 22.1895, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:00:06.452067+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.7, + "humidity": 67.4, + "water_total": 4743.0, + "average_temperature": 31.7, + "experience_temperature": 23.1657, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:10:05.497024+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.5, + "humidity": 65.2, + "water_total": 4804.0, + "average_temperature": 31.9667, + "experience_temperature": 23.9352, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:20:06.656379+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 64.0, + "water_total": 4856.0, + "average_temperature": 32.0667, + "experience_temperature": 21.9095, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:30:06.088502+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 63.3, + "water_total": 4908.0, + "average_temperature": 32.4, + "experience_temperature": 22.1029, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:40:06.321647+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 63.9, + "water_total": 4965.0, + "average_temperature": 32.7333, + "experience_temperature": 21.6133, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T10:50:08.093054+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 62.4, + "water_total": 5030.0, + "average_temperature": 32.3667, + "experience_temperature": 21.8895, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:00:06.016300+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.0, + "humidity": 63.5, + "water_total": 5077.0, + "average_temperature": 32.5333, + "experience_temperature": 21.8048, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:10:06.965089+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 61.8, + "water_total": 5125.0, + "average_temperature": 32.8, + "experience_temperature": 22.2029, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:20:05.687120+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 60.2, + "water_total": 5175.0, + "average_temperature": 32.7, + "experience_temperature": 20.84, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:30:07.441830+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 60.2, + "water_total": 5175.0, + "average_temperature": 32.7, + "experience_temperature": 20.84, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:40:05.674914+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.3, + "humidity": 58.6, + "water_total": 5282.0, + "average_temperature": 32.9667, + "experience_temperature": 19.8438, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T11:50:05.966068+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 60.5, + "water_total": 5351.0, + "average_temperature": 33.1667, + "experience_temperature": 19.481, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:00:06.183201+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.0, + "humidity": 60.0, + "water_total": 5409.0, + "average_temperature": 32.9, + "experience_temperature": 21.4714, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:10:06.092789+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 57.9, + "water_total": 5463.0, + "average_temperature": 33.0667, + "experience_temperature": 18.861, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:20:06.239789+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.4, + "humidity": 57.5, + "water_total": 5520.0, + "average_temperature": 33.1333, + "experience_temperature": 19.319, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:30:06.517904+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.0, + "humidity": 58.6, + "water_total": 5580.0, + "average_temperature": 33.0, + "experience_temperature": 21.2914, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:40:06.075663+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 59.6, + "water_total": 5645.0, + "average_temperature": 33.2, + "experience_temperature": 19.3343, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T12:50:10.796576+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.0, + "humidity": 59.7, + "water_total": 5707.0, + "average_temperature": 33.2, + "experience_temperature": 21.7114, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:00:06.055513+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 60.6, + "water_total": 5778.0, + "average_temperature": 33.1, + "experience_temperature": 21.32, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:10:06.673406+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.3, + "humidity": 59.4, + "water_total": 5837.0, + "average_temperature": 33.4333, + "experience_temperature": 20.4705, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:20:06.041179+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.3, + "humidity": 57.4, + "water_total": 5895.0, + "average_temperature": 33.3333, + "experience_temperature": 19.9705, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:30:06.874701+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.6, + "humidity": 59.0, + "water_total": 5956.0, + "average_temperature": 33.3, + "experience_temperature": 18.8429, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:40:05.908476+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 58.9, + "water_total": 6005.0, + "average_temperature": 33.1, + "experience_temperature": 19.0943, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T13:50:07.490318+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 59.5, + "water_total": 6071.0, + "average_temperature": 33.3333, + "experience_temperature": 19.4476, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T14:10:06.335101+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 59.0, + "water_total": 6178.0, + "average_temperature": 33.0333, + "experience_temperature": 20.9333, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T14:20:07.624041+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.4, + "humidity": 59.5, + "water_total": 6239.0, + "average_temperature": 33.3333, + "experience_temperature": 19.919, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T14:30:06.002417+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.3, + "humidity": 57.4, + "water_total": 6297.0, + "average_temperature": 33.0333, + "experience_temperature": 19.6705, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T14:40:06.503203+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 57.1, + "water_total": 6354.0, + "average_temperature": 33.2333, + "experience_temperature": 18.8676, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T14:50:07.364511+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.5, + "humidity": 57.0, + "water_total": 6414.0, + "average_temperature": 33.1667, + "experience_temperature": 18.781, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T15:10:05.705976+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 58.8, + "water_total": 6519.0, + "average_temperature": 32.9, + "experience_temperature": 21.7029, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T15:20:06.810631+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 56.0, + "water_total": 6583.0, + "average_temperature": 33.0667, + "experience_temperature": 20.3667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T15:30:06.276025+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 59.1, + "water_total": 6637.0, + "average_temperature": 33.0333, + "experience_temperature": 20.9533, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T15:40:06.332438+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 61.2, + "water_total": 6704.0, + "average_temperature": 32.9333, + "experience_temperature": 21.2733, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T15:50:06.216832+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.1, + "humidity": 61.2, + "water_total": 6704.0, + "average_temperature": 32.9333, + "experience_temperature": 21.2733, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T16:10:06.848078+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 71.8, + "water_total": 6759.0, + "average_temperature": 30.7333, + "experience_temperature": 25.4362, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T16:20:06.750256+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 69.4, + "water_total": 6924.0, + "average_temperature": 31.5667, + "experience_temperature": 22.4895, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T16:30:08.928878+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 2.0, + "humidity": 69.9, + "water_total": 6987.0, + "average_temperature": 31.3667, + "experience_temperature": 21.9181, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T16:40:06.071075+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.8, + "humidity": 70.5, + "water_total": 7050.0, + "average_temperature": 31.2667, + "experience_temperature": 22.881, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T16:50:07.481284+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.9, + "humidity": 71.5, + "water_total": 7107.0, + "average_temperature": 31.1333, + "experience_temperature": 22.4762, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T17:10:06.224764+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.8, + "humidity": 72.8, + "water_total": 53.0, + "average_temperature": 30.6667, + "experience_temperature": 22.741, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T17:20:07.195080+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 73.3, + "water_total": 113.0, + "average_temperature": 30.6333, + "experience_temperature": 25.1648, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T17:30:05.525073+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 73.6, + "water_total": 177.0, + "average_temperature": 30.5, + "experience_temperature": 25.5629, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T17:40:06.141674+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 74.2, + "water_total": 241.0, + "average_temperature": 30.2, + "experience_temperature": 24.44, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T17:50:06.178332+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 74.8, + "water_total": 302.0, + "average_temperature": 29.9667, + "experience_temperature": 24.3267, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:00:06.074171+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 74.8, + "water_total": 302.0, + "average_temperature": 29.9667, + "experience_temperature": 24.3267, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:10:06.050905+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 74.3, + "water_total": 337.0, + "average_temperature": 29.4667, + "experience_temperature": 23.7267, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:20:06.945471+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 75.2, + "water_total": 351.0, + "average_temperature": 29.3667, + "experience_temperature": 24.2781, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:30:05.838615+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 76.2, + "water_total": 361.0, + "average_temperature": 29.1333, + "experience_temperature": 24.2448, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:40:06.974031+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 76.7, + "water_total": 385.0, + "average_temperature": 29.3333, + "experience_temperature": 25.0162, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T18:50:06.441525+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 77.6, + "water_total": 480.0, + "average_temperature": 29.2, + "experience_temperature": 25.0629, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:00:06.121314+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 78.2, + "water_total": 555.0, + "average_temperature": 28.7333, + "experience_temperature": 24.2448, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:10:05.563956+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.3, + "humidity": 79.8, + "water_total": 615.0, + "average_temperature": 28.6333, + "experience_temperature": 24.4648, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:20:08.405041+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 80.0, + "water_total": 682.0, + "average_temperature": 28.6333, + "experience_temperature": 24.9762, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:30:05.960237+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 79.0, + "water_total": 747.0, + "average_temperature": 28.5667, + "experience_temperature": 23.7667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:40:06.085093+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 78.6, + "water_total": 813.0, + "average_temperature": 28.5, + "experience_temperature": 26.4486, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T19:50:06.433306+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.0, + "humidity": 80.0, + "water_total": 867.0, + "average_temperature": 28.6, + "experience_temperature": 25.8857, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:00:06.117892+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 80.1, + "water_total": 940.0, + "average_temperature": 28.6, + "experience_temperature": 24.9629, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:10:05.875181+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 79.0, + "water_total": 1005.0, + "average_temperature": 28.4667, + "experience_temperature": 26.9667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:20:05.810334+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 81.8, + "water_total": 1067.0, + "average_temperature": 28.6, + "experience_temperature": 27.1886, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:30:06.571597+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 82.1, + "water_total": 1123.0, + "average_temperature": 28.6333, + "experience_temperature": 25.3962, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:40:06.615391+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 80.2, + "water_total": 1180.0, + "average_temperature": 28.5667, + "experience_temperature": 24.9495, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T20:50:06.494482+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 80.7, + "water_total": 1216.0, + "average_temperature": 28.4667, + "experience_temperature": 27.3067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:00:06.921267+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 81.8, + "water_total": 1277.0, + "average_temperature": 28.6, + "experience_temperature": 25.3029, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:10:06.787825+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 80.9, + "water_total": 1337.0, + "average_temperature": 28.3667, + "experience_temperature": 27.2467, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:20:06.008774+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.2, + "humidity": 80.6, + "water_total": 1406.0, + "average_temperature": 28.5333, + "experience_temperature": 24.9962, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:30:06.447769+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 80.3, + "water_total": 1460.0, + "average_temperature": 28.4333, + "experience_temperature": 26.7219, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:40:06.563859+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 81.9, + "water_total": 1521.0, + "average_temperature": 28.4, + "experience_temperature": 27.9514, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T21:50:06.379956+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 81.2, + "water_total": 1581.0, + "average_temperature": 28.5667, + "experience_temperature": 24.2067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:00:07.666757+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 1.4, + "humidity": 81.2, + "water_total": 1581.0, + "average_temperature": 28.5667, + "experience_temperature": 24.2067, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:10:09.146949+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 80.9, + "water_total": 1680.0, + "average_temperature": 28.4, + "experience_temperature": 27.7514, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:20:06.534710+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 81.6, + "water_total": 1733.0, + "average_temperature": 28.4, + "experience_temperature": 27.42, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:30:06.376951+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.0, + "water_total": 1775.0, + "average_temperature": 28.2667, + "experience_temperature": 28.0381, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:40:07.750046+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 1829.0, + "average_temperature": 28.2333, + "experience_temperature": 27.4533, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T22:50:06.665240+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.5, + "water_total": 1881.0, + "average_temperature": 28.2667, + "experience_temperature": 27.6667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:00:06.555359+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 84.0, + "water_total": 1928.0, + "average_temperature": 28.1667, + "experience_temperature": 27.6667, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:10:06.353309+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.8, + "water_total": 1980.0, + "average_temperature": 28.1333, + "experience_temperature": 28.0648, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:20:05.941586+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.7, + "humidity": 83.9, + "water_total": 2023.0, + "average_temperature": 28.0333, + "experience_temperature": 27.5133, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:30:06.920286+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.6, + "humidity": 83.0, + "water_total": 2079.0, + "average_temperature": 28.1333, + "experience_temperature": 27.9048, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:40:05.879726+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.9, + "water_total": 2124.0, + "average_temperature": 27.2667, + "experience_temperature": 26.4752, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-10T23:50:06.755708+07:00", + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.9, + "water_total": 2159.0, + "average_temperature": 27.5, + "experience_temperature": 26.7086, + "chill_factor": 4.7143 + }, + { + "timestamp": "2026-06-11T00:00:06.573780+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 84.7, + "water_total": 2203.0, + "average_temperature": 27.6667, + "experience_temperature": 27.0067, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T00:10:06.343354+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 2259.0, + "average_temperature": 27.5667, + "experience_temperature": 27.3567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T00:20:06.595824+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.9, + "water_total": 2308.0, + "average_temperature": 27.8, + "experience_temperature": 27.63, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T00:30:06.244999+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 2366.0, + "average_temperature": 27.8667, + "experience_temperature": 27.6167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T00:40:06.243954+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.9, + "humidity": 84.8, + "water_total": 2410.0, + "average_temperature": 27.7333, + "experience_temperature": 26.6433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T00:50:06.586479+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 85.0, + "water_total": 2445.0, + "average_temperature": 28.0, + "experience_temperature": 27.4, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:00:06.030827+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.2, + "water_total": 2487.0, + "average_temperature": 27.8, + "experience_temperature": 27.94, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:10:06.676979+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 83.8, + "water_total": 2529.0, + "average_temperature": 27.6667, + "experience_temperature": 27.2767, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:20:07.315045+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 83.5, + "water_total": 2565.0, + "average_temperature": 27.6667, + "experience_temperature": 27.6667, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:30:06.287144+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 84.4, + "water_total": 2604.0, + "average_temperature": 27.8, + "experience_temperature": 27.08, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:40:06.438041+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.1, + "water_total": 2631.0, + "average_temperature": 27.3667, + "experience_temperature": 27.4867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T01:50:06.039164+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.9, + "humidity": 83.9, + "water_total": 2645.0, + "average_temperature": 27.0, + "experience_temperature": 25.73, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:00:06.360671+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.1, + "water_total": 2654.0, + "average_temperature": 26.8667, + "experience_temperature": 26.5367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:10:07.056331+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 86.7, + "water_total": 2673.0, + "average_temperature": 27.2667, + "experience_temperature": 27.4567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:20:06.588957+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.4, + "humidity": 84.9, + "water_total": 2727.0, + "average_temperature": 27.5667, + "experience_temperature": 28.7467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:30:06.265050+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 83.9, + "water_total": 2811.0, + "average_temperature": 27.0667, + "experience_temperature": 26.2467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:40:06.821057+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.9, + "humidity": 85.2, + "water_total": 2852.0, + "average_temperature": 26.5667, + "experience_temperature": 25.5567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T02:50:06.669724+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 86.4, + "water_total": 2889.0, + "average_temperature": 26.8333, + "experience_temperature": 26.5133, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:00:06.224958+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.5, + "humidity": 86.5, + "water_total": 2930.0, + "average_temperature": 27.0667, + "experience_temperature": 28.1167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:10:06.221977+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 87.1, + "water_total": 2970.0, + "average_temperature": 26.9, + "experience_temperature": 27.62, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:20:05.851870+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 85.1, + "water_total": 3004.0, + "average_temperature": 26.7, + "experience_temperature": 27.02, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:30:06.880397+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 83.7, + "water_total": 3042.0, + "average_temperature": 26.7333, + "experience_temperature": 26.3233, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:40:06.317878+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 85.5, + "water_total": 3077.0, + "average_temperature": 26.9, + "experience_temperature": 26.4, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T03:50:06.599158+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.5, + "humidity": 85.0, + "water_total": 3146.0, + "average_temperature": 27.2, + "experience_temperature": 27.95, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:00:07.351782+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 85.4, + "water_total": 3215.0, + "average_temperature": 26.4333, + "experience_temperature": 26.3633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:10:07.269788+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 85.6, + "water_total": 3241.0, + "average_temperature": 25.7333, + "experience_temperature": 25.2533, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:20:06.273803+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.9, + "humidity": 86.0, + "water_total": 3254.0, + "average_temperature": 25.8333, + "experience_temperature": 24.9833, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:30:06.245084+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 86.2, + "water_total": 3272.0, + "average_temperature": 26.1, + "experience_temperature": 26.19, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:40:07.001975+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 86.4, + "water_total": 3284.0, + "average_temperature": 25.9, + "experience_temperature": 26.48, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T04:50:06.438280+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 86.5, + "water_total": 3293.0, + "average_temperature": 25.9, + "experience_temperature": 25.6, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:00:06.778400+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 85.7, + "water_total": 3305.0, + "average_temperature": 25.8667, + "experience_temperature": 25.8567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:10:07.737043+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.7, + "water_total": 3378.0, + "average_temperature": 26.9667, + "experience_temperature": 27.2067, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:20:06.312954+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.8, + "humidity": 83.3, + "water_total": 3447.0, + "average_temperature": 26.0, + "experience_temperature": 25.06, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:30:06.719792+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 85.5, + "water_total": 3473.0, + "average_temperature": 25.9667, + "experience_temperature": 25.9167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:40:06.987286+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 3516.0, + "average_temperature": 26.0333, + "experience_temperature": 25.8233, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T05:50:06.864577+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 3573.0, + "average_temperature": 26.3333, + "experience_temperature": 25.7033, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:00:06.464200+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.4, + "humidity": 82.5, + "water_total": 3641.0, + "average_temperature": 26.5333, + "experience_temperature": 27.2333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:10:07.725329+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.1, + "water_total": 3685.0, + "average_temperature": 25.8333, + "experience_temperature": 25.9533, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:20:06.840757+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.5, + "humidity": 86.8, + "water_total": 3721.0, + "average_temperature": 26.3333, + "experience_temperature": 27.4433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:30:09.035893+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 3804.0, + "average_temperature": 26.2, + "experience_temperature": 25.99, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:40:06.480667+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.9, + "water_total": 3852.0, + "average_temperature": 25.7333, + "experience_temperature": 25.5633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T06:50:07.681619+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 84.4, + "water_total": 3888.0, + "average_temperature": 26.0333, + "experience_temperature": 25.7633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:00:06.803222+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 85.6, + "water_total": 3940.0, + "average_temperature": 25.9667, + "experience_temperature": 26.3867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:10:07.980064+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.0, + "water_total": 3987.0, + "average_temperature": 26.5667, + "experience_temperature": 26.6667, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:20:06.507817+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.6, + "humidity": 84.4, + "water_total": 4042.0, + "average_temperature": 26.8, + "experience_temperature": 26.98, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:30:06.712494+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.5, + "humidity": 83.2, + "water_total": 4092.0, + "average_temperature": 27.1, + "experience_temperature": 27.49, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:40:06.348543+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 83.4, + "water_total": 4149.0, + "average_temperature": 27.4, + "experience_temperature": 26.93, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T07:50:06.783297+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 81.8, + "water_total": 4208.0, + "average_temperature": 27.7333, + "experience_temperature": 26.9433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:00:06.897659+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 81.5, + "water_total": 4269.0, + "average_temperature": 27.7333, + "experience_temperature": 26.8833, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:10:06.393895+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 0.7, + "humidity": 81.5, + "water_total": 4269.0, + "average_temperature": 27.7333, + "experience_temperature": 26.8833, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:20:07.394594+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 79.0, + "water_total": 4348.0, + "average_temperature": 28.3, + "experience_temperature": 24.25, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:30:06.311873+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 77.1, + "water_total": 4410.0, + "average_temperature": 29.0, + "experience_temperature": 24.57, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:40:07.166692+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 75.4, + "water_total": 4469.0, + "average_temperature": 29.5667, + "experience_temperature": 25.2467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T08:50:06.585008+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 73.4, + "water_total": 4520.0, + "average_temperature": 29.7667, + "experience_temperature": 24.1467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:00:06.617306+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 73.4, + "water_total": 4520.0, + "average_temperature": 29.7667, + "experience_temperature": 24.1467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:10:07.639237+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.6, + "humidity": 71.5, + "water_total": 4638.0, + "average_temperature": 30.3, + "experience_temperature": 23.4, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:20:06.803232+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.6, + "humidity": 71.9, + "water_total": 4691.0, + "average_temperature": 30.3333, + "experience_temperature": 23.5133, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:30:08.161688+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.6, + "humidity": 71.4, + "water_total": 4742.0, + "average_temperature": 30.7667, + "experience_temperature": 23.8467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:40:07.056625+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.8, + "humidity": 70.0, + "water_total": 4799.0, + "average_temperature": 30.9667, + "experience_temperature": 22.8667, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T09:50:07.130159+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 4858.0, + "average_temperature": 31.3333, + "experience_temperature": 22.4033, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:00:11.084248+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 4858.0, + "average_temperature": 31.3333, + "experience_temperature": 22.4033, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:10:07.351092+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 66.2, + "water_total": 4984.0, + "average_temperature": 31.8667, + "experience_temperature": 20.3067, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:20:07.646471+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 65.2, + "water_total": 5040.0, + "average_temperature": 31.9, + "experience_temperature": 20.59, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:30:07.399232+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.8, + "humidity": 64.8, + "water_total": 5095.0, + "average_temperature": 31.8333, + "experience_temperature": 22.6933, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:40:06.660102+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.2, + "humidity": 64.5, + "water_total": 5153.0, + "average_temperature": 31.7333, + "experience_temperature": 20.7333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T10:50:06.571405+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 63.7, + "water_total": 5210.0, + "average_temperature": 32.0333, + "experience_temperature": 22.2233, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:00:06.803979+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 62.7, + "water_total": 5269.0, + "average_temperature": 32.8333, + "experience_temperature": 21.0233, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:10:10.348143+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 59.5, + "water_total": 5323.0, + "average_temperature": 32.7, + "experience_temperature": 20.25, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:20:07.143772+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.2, + "humidity": 59.3, + "water_total": 5323.0, + "average_temperature": 32.8, + "experience_temperature": 20.76, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:30:07.175924+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 60.9, + "water_total": 5440.0, + "average_temperature": 32.6, + "experience_temperature": 19.53, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:40:06.423242+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 61.5, + "water_total": 5502.0, + "average_temperature": 32.7667, + "experience_temperature": 19.8167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T11:50:08.817690+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.1, + "humidity": 60.5, + "water_total": 5558.0, + "average_temperature": 33.0333, + "experience_temperature": 21.6833, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:00:06.577233+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.6, + "humidity": 59.6, + "water_total": 5625.0, + "average_temperature": 33.0, + "experience_temperature": 19.22, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:10:06.059032+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 60.5, + "water_total": 5688.0, + "average_temperature": 32.8667, + "experience_temperature": 19.7167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:20:07.421487+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 61.0, + "water_total": 5745.0, + "average_temperature": 33.1, + "experience_temperature": 20.5, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:30:06.563717+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 60.5, + "water_total": 5796.0, + "average_temperature": 32.9, + "experience_temperature": 20.2, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:40:07.507762+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 60.5, + "water_total": 5796.0, + "average_temperature": 32.9, + "experience_temperature": 20.2, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T12:50:06.131063+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 59.4, + "water_total": 5918.0, + "average_temperature": 33.0667, + "experience_temperature": 19.6967, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:00:06.206825+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 59.6, + "water_total": 5976.0, + "average_temperature": 33.0, + "experience_temperature": 22.37, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:10:06.610976+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 58.5, + "water_total": 6025.0, + "average_temperature": 32.9, + "experience_temperature": 20.25, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:20:08.253003+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 55.9, + "water_total": 6082.0, + "average_temperature": 32.7333, + "experience_temperature": 19.5633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:30:05.757279+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 56.2, + "water_total": 6135.0, + "average_temperature": 32.9667, + "experience_temperature": 19.8567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:40:08.069351+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 55.8, + "water_total": 6187.0, + "average_temperature": 32.8667, + "experience_temperature": 18.7767, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T13:50:06.758179+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 55.8, + "water_total": 6187.0, + "average_temperature": 32.8667, + "experience_temperature": 18.7767, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T14:10:07.055274+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.2, + "humidity": 57.6, + "water_total": 6352.0, + "average_temperature": 33.3, + "experience_temperature": 20.92, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T14:20:06.614038+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 57.6, + "water_total": 6414.0, + "average_temperature": 33.1667, + "experience_temperature": 19.8867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T14:30:06.937716+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.7, + "humidity": 59.3, + "water_total": 6474.0, + "average_temperature": 33.3667, + "experience_temperature": 19.0767, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T14:40:12.615574+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.6, + "humidity": 57.9, + "water_total": 6543.0, + "average_temperature": 33.2667, + "experience_temperature": 19.1467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T14:50:10.511519+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 56.0, + "water_total": 6607.0, + "average_temperature": 33.1333, + "experience_temperature": 19.0833, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T15:10:05.919630+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 65.9, + "water_total": 6731.0, + "average_temperature": 32.9333, + "experience_temperature": 20.8633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T15:20:08.267092+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.6, + "humidity": 67.5, + "water_total": 6789.0, + "average_temperature": 32.6, + "experience_temperature": 20.4, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T15:30:06.246671+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 68.1, + "water_total": 6852.0, + "average_temperature": 32.3667, + "experience_temperature": 20.7367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T15:40:06.097870+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.6, + "humidity": 68.6, + "water_total": 6905.0, + "average_temperature": 32.3, + "experience_temperature": 20.32, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T15:50:06.917466+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.4, + "humidity": 69.5, + "water_total": 6957.0, + "average_temperature": 32.0333, + "experience_temperature": 21.1333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T16:10:08.662247+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.6, + "humidity": 68.8, + "water_total": 7051.0, + "average_temperature": 31.8, + "experience_temperature": 19.86, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T16:20:08.192514+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.5, + "humidity": 68.5, + "water_total": 7108.0, + "average_temperature": 31.8, + "experience_temperature": 20.25, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T16:30:07.066531+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.1, + "humidity": 69.5, + "water_total": 7156.0, + "average_temperature": 31.5667, + "experience_temperature": 22.0167, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T16:40:05.863831+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.1, + "humidity": 69.2, + "water_total": 7225.0, + "average_temperature": 31.4667, + "experience_temperature": 21.8567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T16:50:06.569976+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.2, + "humidity": 71.0, + "water_total": 7279.0, + "average_temperature": 31.2667, + "experience_temperature": 21.5667, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T17:10:05.679063+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 2.3, + "humidity": 71.3, + "water_total": 49.0, + "average_temperature": 30.7333, + "experience_temperature": 20.6433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T17:20:06.171071+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.8, + "humidity": 72.2, + "water_total": 108.0, + "average_temperature": 30.7, + "experience_temperature": 23.04, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T17:30:06.909021+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.8, + "humidity": 73.0, + "water_total": 169.0, + "average_temperature": 30.4667, + "experience_temperature": 22.9667, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T17:40:05.889501+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.7, + "humidity": 73.4, + "water_total": 222.0, + "average_temperature": 30.1333, + "experience_temperature": 23.1633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T17:50:05.661173+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.8, + "humidity": 74.5, + "water_total": 276.0, + "average_temperature": 29.9333, + "experience_temperature": 22.7333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:00:06.175395+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 74.8, + "water_total": 298.0, + "average_temperature": 29.7, + "experience_temperature": 22.11, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:10:06.289742+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 77.1, + "water_total": 312.0, + "average_temperature": 29.5333, + "experience_temperature": 25.5533, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:20:07.941405+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 78.7, + "water_total": 326.0, + "average_temperature": 29.2333, + "experience_temperature": 25.5733, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:30:06.024299+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 78.5, + "water_total": 340.0, + "average_temperature": 29.2, + "experience_temperature": 25.5, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:40:06.063656+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 76.9, + "water_total": 365.0, + "average_temperature": 29.6333, + "experience_temperature": 22.4633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T18:50:06.107151+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 78.1, + "water_total": 461.0, + "average_temperature": 29.8667, + "experience_temperature": 22.9367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:00:05.873291+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.9, + "humidity": 78.1, + "water_total": 461.0, + "average_temperature": 29.8667, + "experience_temperature": 22.9367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:10:06.040439+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 78.8, + "water_total": 609.0, + "average_temperature": 29.2333, + "experience_temperature": 25.1433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:20:08.597074+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 79.2, + "water_total": 676.0, + "average_temperature": 29.0667, + "experience_temperature": 24.6067, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:30:06.111427+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 79.1, + "water_total": 753.0, + "average_temperature": 29.1667, + "experience_temperature": 25.1367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:40:08.597593+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 78.8, + "water_total": 821.0, + "average_temperature": 29.2, + "experience_temperature": 24.66, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T19:50:05.960129+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 79.1, + "water_total": 898.0, + "average_temperature": 29.3333, + "experience_temperature": 25.3033, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:00:06.169266+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.5, + "humidity": 77.9, + "water_total": 967.0, + "average_temperature": 29.5667, + "experience_temperature": 24.3967, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:10:06.434292+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.1, + "humidity": 78.4, + "water_total": 1035.0, + "average_temperature": 29.3667, + "experience_temperature": 26.0967, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:20:06.971795+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 80.6, + "water_total": 1092.0, + "average_temperature": 29.1667, + "experience_temperature": 25.4367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:30:09.523463+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 79.2, + "water_total": 1149.0, + "average_temperature": 29.2667, + "experience_temperature": 25.2567, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:40:06.142213+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 80.8, + "water_total": 1198.0, + "average_temperature": 29.2, + "experience_temperature": 25.06, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T20:50:07.998256+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 81.4, + "water_total": 1253.0, + "average_temperature": 28.8333, + "experience_temperature": 25.2633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:00:05.957124+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 82.1, + "water_total": 1293.0, + "average_temperature": 28.5, + "experience_temperature": 24.62, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:10:05.806024+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 81.8, + "water_total": 1335.0, + "average_temperature": 28.7, + "experience_temperature": 24.76, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:20:09.690463+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 81.7, + "water_total": 1388.0, + "average_temperature": 28.8667, + "experience_temperature": 25.8067, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:30:08.869095+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 81.3, + "water_total": 1445.0, + "average_temperature": 28.9, + "experience_temperature": 25.31, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:40:06.668981+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 81.4, + "water_total": 1486.0, + "average_temperature": 28.7667, + "experience_temperature": 24.7467, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T21:50:05.999981+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 81.5, + "water_total": 1550.0, + "average_temperature": 28.7333, + "experience_temperature": 25.6333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:00:09.141358+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 81.4, + "water_total": 1604.0, + "average_temperature": 28.6333, + "experience_temperature": 25.0633, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:10:06.243364+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.5, + "humidity": 81.3, + "water_total": 1673.0, + "average_temperature": 28.5333, + "experience_temperature": 24.0433, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:20:05.884738+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 81.3, + "water_total": 1728.0, + "average_temperature": 28.4667, + "experience_temperature": 24.4267, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:30:06.028430+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 82.1, + "water_total": 1774.0, + "average_temperature": 28.1667, + "experience_temperature": 25.1867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:40:06.000225+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 1818.0, + "average_temperature": 28.0667, + "experience_temperature": 25.2867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T22:50:07.312349+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 82.6, + "water_total": 1866.0, + "average_temperature": 28.4, + "experience_temperature": 25.07, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:00:05.809147+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.0, + "humidity": 83.7, + "water_total": 1913.0, + "average_temperature": 28.1, + "experience_temperature": 26.34, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:10:06.363366+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.3, + "humidity": 83.1, + "water_total": 1955.0, + "average_temperature": 27.7667, + "experience_temperature": 24.5367, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:20:05.592821+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 83.6, + "water_total": 2011.0, + "average_temperature": 27.6667, + "experience_temperature": 24.0867, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:30:05.641703+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 84.0, + "water_total": 2064.0, + "average_temperature": 27.6333, + "experience_temperature": 24.1333, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:40:05.786257+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.4, + "humidity": 84.3, + "water_total": 2079.0, + "average_temperature": 27.6667, + "experience_temperature": 24.2267, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-11T23:50:06.381074+07:00", + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 84.3, + "water_total": 2092.0, + "average_temperature": 27.6333, + "experience_temperature": 25.0933, + "chill_factor": 4.5 + }, + { + "timestamp": "2026-06-12T00:00:14.588678+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 84.3, + "water_total": 2092.0, + "average_temperature": 27.6333, + "experience_temperature": 25.2648, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T00:10:05.646146+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 85.7, + "water_total": 2121.0, + "average_temperature": 27.6333, + "experience_temperature": 24.6733, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T00:20:05.893238+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 84.5, + "water_total": 2211.0, + "average_temperature": 27.5667, + "experience_temperature": 24.8024, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T00:30:05.932711+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 84.4, + "water_total": 2270.0, + "average_temperature": 27.6333, + "experience_temperature": 24.849, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T00:40:05.748028+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 84.0, + "water_total": 2327.0, + "average_temperature": 27.5333, + "experience_temperature": 24.2333, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T00:50:05.590460+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 85.9, + "water_total": 2376.0, + "average_temperature": 27.5, + "experience_temperature": 27.63, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:00:06.874419+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.4, + "water_total": 2435.0, + "average_temperature": 27.3667, + "experience_temperature": 27.1967, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:10:06.114462+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 85.6, + "water_total": 2497.0, + "average_temperature": 27.4, + "experience_temperature": 27.9057, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:20:05.521151+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 83.5, + "water_total": 2560.0, + "average_temperature": 27.3, + "experience_temperature": 26.5143, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:30:06.392035+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.5, + "humidity": 84.3, + "water_total": 2626.0, + "average_temperature": 27.6333, + "experience_temperature": 23.9576, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:40:06.182233+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.5, + "humidity": 84.3, + "water_total": 2626.0, + "average_temperature": 27.6333, + "experience_temperature": 23.9576, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T01:50:06.486023+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.9, + "humidity": 86.0, + "water_total": 2687.0, + "average_temperature": 26.9, + "experience_temperature": 26.1786, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:00:06.114238+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 2744.0, + "average_temperature": 27.2333, + "experience_temperature": 27.1233, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:10:06.082804+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 2805.0, + "average_temperature": 27.3333, + "experience_temperature": 27.2233, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:20:06.008504+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 84.8, + "water_total": 2853.0, + "average_temperature": 27.4, + "experience_temperature": 26.8743, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:30:05.842202+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.5, + "humidity": 83.7, + "water_total": 2907.0, + "average_temperature": 27.4333, + "experience_temperature": 27.9948, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:40:06.052495+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 2974.0, + "average_temperature": 27.4667, + "experience_temperature": 27.3167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T02:50:06.213523+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 3024.0, + "average_temperature": 27.4, + "experience_temperature": 27.8457, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:00:05.696626+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.1, + "humidity": 85.9, + "water_total": 3068.0, + "average_temperature": 27.6333, + "experience_temperature": 26.0205, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:10:06.387577+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 83.5, + "water_total": 3114.0, + "average_temperature": 27.4, + "experience_temperature": 26.6143, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:20:06.318197+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 85.0, + "water_total": 3162.0, + "average_temperature": 27.4667, + "experience_temperature": 27.8524, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:30:06.009897+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.0, + "water_total": 3210.0, + "average_temperature": 27.4667, + "experience_temperature": 27.2167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:40:06.762419+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.8, + "water_total": 3275.0, + "average_temperature": 27.3, + "experience_temperature": 27.01, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T03:50:05.825891+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 85.0, + "water_total": 3322.0, + "average_temperature": 27.0, + "experience_temperature": 26.95, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:00:06.089982+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 85.5, + "water_total": 3370.0, + "average_temperature": 26.6667, + "experience_temperature": 26.7167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:10:05.703725+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 85.9, + "water_total": 3395.0, + "average_temperature": 26.5, + "experience_temperature": 26.1943, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:20:07.093900+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 86.9, + "water_total": 3408.0, + "average_temperature": 26.4333, + "experience_temperature": 27.199, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:30:05.998094+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.9, + "humidity": 85.7, + "water_total": 3421.0, + "average_temperature": 26.4333, + "experience_temperature": 25.6519, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:40:05.836254+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.9, + "humidity": 86.2, + "water_total": 3431.0, + "average_temperature": 26.4, + "experience_temperature": 25.7186, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T04:50:06.492581+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 85.5, + "water_total": 3443.0, + "average_temperature": 26.2, + "experience_temperature": 26.25, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:00:05.695054+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 85.8, + "water_total": 3457.0, + "average_temperature": 26.2, + "experience_temperature": 25.8743, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:10:07.044951+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 85.4, + "water_total": 3494.0, + "average_temperature": 27.1333, + "experience_temperature": 26.7276, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:20:06.415326+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.5, + "humidity": 83.7, + "water_total": 3573.0, + "average_temperature": 26.8667, + "experience_temperature": 27.4281, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:30:06.366739+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 82.6, + "water_total": 3638.0, + "average_temperature": 26.5333, + "experience_temperature": 26.0033, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:40:06.012874+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.9, + "humidity": 83.7, + "water_total": 3681.0, + "average_temperature": 26.5, + "experience_temperature": 25.3186, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T05:50:06.514631+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 85.1, + "water_total": 3725.0, + "average_temperature": 26.7667, + "experience_temperature": 27.1724, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:00:06.532457+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.2, + "water_total": 3772.0, + "average_temperature": 26.5, + "experience_temperature": 26.09, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:10:06.110691+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 83.3, + "water_total": 3822.0, + "average_temperature": 26.5333, + "experience_temperature": 26.579, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:20:06.277645+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 83.4, + "water_total": 3888.0, + "average_temperature": 27.0, + "experience_temperature": 27.0657, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:30:06.807831+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 81.8, + "water_total": 3964.0, + "average_temperature": 26.5333, + "experience_temperature": 25.8433, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:40:06.431180+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.9, + "humidity": 83.2, + "water_total": 4005.0, + "average_temperature": 26.2667, + "experience_temperature": 24.9852, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T06:50:06.342469+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.1, + "water_total": 4038.0, + "average_temperature": 26.4333, + "experience_temperature": 26.0033, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:00:07.705729+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 82.8, + "water_total": 4078.0, + "average_temperature": 26.6333, + "experience_temperature": 26.1433, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:10:06.856717+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 82.8, + "water_total": 4078.0, + "average_temperature": 26.6333, + "experience_temperature": 26.1433, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:20:06.499761+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 81.8, + "water_total": 4185.0, + "average_temperature": 26.7333, + "experience_temperature": 26.479, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:30:06.239036+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 83.2, + "water_total": 4220.0, + "average_temperature": 27.4333, + "experience_temperature": 27.459, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:40:08.107045+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 79.1, + "water_total": 4283.0, + "average_temperature": 27.4667, + "experience_temperature": 26.2367, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T07:50:06.208595+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 77.7, + "water_total": 4353.0, + "average_temperature": 27.4, + "experience_temperature": 25.89, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:00:06.411386+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 77.7, + "water_total": 4353.0, + "average_temperature": 27.4, + "experience_temperature": 25.89, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:10:06.725463+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 77.4, + "water_total": 4411.0, + "average_temperature": 27.7667, + "experience_temperature": 24.0181, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:20:06.239139+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 76.2, + "water_total": 4467.0, + "average_temperature": 27.9333, + "experience_temperature": 23.9448, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:30:06.384343+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.1, + "humidity": 74.2, + "water_total": 4595.0, + "average_temperature": 28.6, + "experience_temperature": 24.6471, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:40:07.034048+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.1, + "humidity": 74.2, + "water_total": 4595.0, + "average_temperature": 28.6, + "experience_temperature": 24.6471, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T08:50:07.150513+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.1, + "humidity": 73.5, + "water_total": 4714.0, + "average_temperature": 29.4333, + "experience_temperature": 25.3405, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:00:07.286960+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.7, + "humidity": 72.1, + "water_total": 4763.0, + "average_temperature": 29.7, + "experience_temperature": 22.7129, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:10:06.685234+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.7, + "humidity": 71.4, + "water_total": 4815.0, + "average_temperature": 29.8, + "experience_temperature": 22.6729, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:20:06.438050+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.6, + "humidity": 71.9, + "water_total": 4863.0, + "average_temperature": 30.2667, + "experience_temperature": 23.6752, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:30:06.578169+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 70.1, + "water_total": 4930.0, + "average_temperature": 30.5, + "experience_temperature": 25.2914, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:40:07.524217+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.6, + "humidity": 70.8, + "water_total": 4987.0, + "average_temperature": 30.5667, + "experience_temperature": 23.7552, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T09:50:07.877238+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.8, + "humidity": 69.4, + "water_total": 5027.0, + "average_temperature": 30.7, + "experience_temperature": 22.7371, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:00:07.350928+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 70.8, + "water_total": 5109.0, + "average_temperature": 31.4, + "experience_temperature": 25.46, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:10:06.486036+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.2, + "humidity": 68.6, + "water_total": 5180.0, + "average_temperature": 31.5333, + "experience_temperature": 21.6676, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:20:08.045149+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 5246.0, + "average_temperature": 31.5, + "experience_temperature": 22.7614, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:30:06.636424+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.8, + "humidity": 68.0, + "water_total": 5303.0, + "average_temperature": 31.7667, + "experience_temperature": 23.5238, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:40:06.055095+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 66.7, + "water_total": 5354.0, + "average_temperature": 31.8667, + "experience_temperature": 22.9281, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T10:50:06.707478+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 67.9, + "water_total": 5416.0, + "average_temperature": 31.8667, + "experience_temperature": 22.7324, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:00:06.662231+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 67.2, + "water_total": 5483.0, + "average_temperature": 32.1, + "experience_temperature": 23.2614, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:10:06.905504+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.4, + "humidity": 66.3, + "water_total": 5547.0, + "average_temperature": 32.5333, + "experience_temperature": 21.3362, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:20:06.328283+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 65.9, + "water_total": 5603.0, + "average_temperature": 32.3, + "experience_temperature": 22.7657, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:30:06.420615+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 67.2, + "water_total": 5647.0, + "average_temperature": 32.5, + "experience_temperature": 23.6614, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:40:06.699298+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 66.0, + "water_total": 5708.0, + "average_temperature": 32.4667, + "experience_temperature": 23.3881, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T11:50:06.620007+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 65.1, + "water_total": 5764.0, + "average_temperature": 32.7667, + "experience_temperature": 23.0724, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:00:06.419883+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.8, + "humidity": 63.5, + "water_total": 5817.0, + "average_temperature": 32.9667, + "experience_temperature": 19.4667, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:10:06.768359+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.4, + "humidity": 61.9, + "water_total": 5873.0, + "average_temperature": 32.7, + "experience_temperature": 20.6229, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:20:06.952794+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.3, + "humidity": 62.5, + "water_total": 5932.0, + "average_temperature": 32.5667, + "experience_temperature": 21.0452, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:30:08.053319+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 62.9, + "water_total": 5975.0, + "average_temperature": 32.3667, + "experience_temperature": 22.6681, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:40:07.504422+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.8, + "humidity": 63.1, + "water_total": 6043.0, + "average_temperature": 33.0333, + "experience_temperature": 19.4533, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T12:50:08.215812+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.5, + "humidity": 63.4, + "water_total": 6101.0, + "average_temperature": 33.2, + "experience_temperature": 20.9871, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:00:06.332668+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.8, + "humidity": 62.1, + "water_total": 6161.0, + "average_temperature": 33.2, + "experience_temperature": 19.42, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:10:06.804274+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 3.0, + "humidity": 62.7, + "water_total": 6226.0, + "average_temperature": 33.2, + "experience_temperature": 18.6686, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:20:08.779359+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.4, + "humidity": 62.0, + "water_total": 6271.0, + "average_temperature": 33.0, + "experience_temperature": 20.9429, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:30:08.744350+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.6, + "humidity": 59.3, + "water_total": 6351.0, + "average_temperature": 32.8333, + "experience_temperature": 19.3648, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:40:11.890331+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.4, + "humidity": 59.9, + "water_total": 6409.0, + "average_temperature": 33.0333, + "experience_temperature": 20.5562, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T13:50:06.563058+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 3.2, + "humidity": 59.1, + "water_total": 6466.0, + "average_temperature": 33.0667, + "experience_temperature": 16.9438, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T14:10:06.809711+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 3.0, + "humidity": 60.0, + "water_total": 6589.0, + "average_temperature": 33.5333, + "experience_temperature": 18.4619, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T14:20:11.561449+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.4, + "humidity": 60.2, + "water_total": 6638.0, + "average_temperature": 32.9, + "experience_temperature": 20.4829, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T14:30:11.875899+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.6, + "humidity": 62.1, + "water_total": 6681.0, + "average_temperature": 32.6667, + "experience_temperature": 19.7581, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T14:40:07.593853+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.5, + "humidity": 62.5, + "water_total": 6751.0, + "average_temperature": 32.5, + "experience_temperature": 20.1071, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T14:50:07.575248+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.3, + "humidity": 64.3, + "water_total": 6824.0, + "average_temperature": 32.3667, + "experience_temperature": 21.2052, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T15:10:08.093662+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 69.0, + "water_total": 6956.0, + "average_temperature": 32.1, + "experience_temperature": 23.1857, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T15:20:06.847572+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 69.0, + "water_total": 6956.0, + "average_temperature": 32.1, + "experience_temperature": 23.1857, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T15:30:07.448624+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.8, + "humidity": 72.3, + "water_total": 7085.0, + "average_temperature": 31.7, + "experience_temperature": 24.3171, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T15:40:06.622801+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.1, + "humidity": 74.0, + "water_total": 7141.0, + "average_temperature": 31.7, + "experience_temperature": 23.35, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T15:50:06.715739+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.1, + "humidity": 74.0, + "water_total": 7141.0, + "average_temperature": 31.7, + "experience_temperature": 23.35, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T16:10:07.358257+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.7, + "humidity": 72.2, + "water_total": 7251.0, + "average_temperature": 29.7, + "experience_temperature": 22.7329, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T16:20:06.415882+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.0, + "humidity": 72.9, + "water_total": 7380.0, + "average_temperature": 31.5333, + "experience_temperature": 23.399, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T16:30:07.221011+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 2.1, + "humidity": 73.0, + "water_total": 7442.0, + "average_temperature": 31.4667, + "experience_temperature": 22.9167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T16:40:08.585684+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.7, + "humidity": 73.1, + "water_total": 7509.0, + "average_temperature": 31.4, + "experience_temperature": 24.6129, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T16:50:06.161687+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.9, + "humidity": 72.9, + "water_total": 7578.0, + "average_temperature": 31.3667, + "experience_temperature": 23.6681, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T17:10:06.234427+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 72.2, + "water_total": 58.0, + "average_temperature": 29.4333, + "experience_temperature": 24.209, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T17:20:05.583493+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 74.1, + "water_total": 112.0, + "average_temperature": 29.0667, + "experience_temperature": 24.6581, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T17:30:06.115261+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 75.2, + "water_total": 160.0, + "average_temperature": 28.8667, + "experience_temperature": 24.2424, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T17:40:08.845244+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 77.4, + "water_total": 204.0, + "average_temperature": 28.7667, + "experience_temperature": 25.0181, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T17:50:06.441567+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 77.7, + "water_total": 253.0, + "average_temperature": 28.3667, + "experience_temperature": 24.2424, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:00:06.320537+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 79.2, + "water_total": 269.0, + "average_temperature": 28.3333, + "experience_temperature": 24.0733, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:10:07.413092+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 79.3, + "water_total": 283.0, + "average_temperature": 28.3, + "experience_temperature": 24.4957, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:20:06.894073+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 80.4, + "water_total": 297.0, + "average_temperature": 28.1, + "experience_temperature": 24.5157, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:30:06.654386+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 80.8, + "water_total": 309.0, + "average_temperature": 27.9667, + "experience_temperature": 24.4624, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:40:06.174120+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 81.6, + "water_total": 323.0, + "average_temperature": 28.2667, + "experience_temperature": 24.4867, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T18:50:06.573242+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 82.2, + "water_total": 422.0, + "average_temperature": 28.1667, + "experience_temperature": 24.9424, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:00:06.564220+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.4, + "humidity": 82.2, + "water_total": 501.0, + "average_temperature": 27.9333, + "experience_temperature": 24.2733, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:10:06.853465+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 82.7, + "water_total": 567.0, + "average_temperature": 27.7667, + "experience_temperature": 27.6924, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:20:06.349768+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 81.9, + "water_total": 637.0, + "average_temperature": 27.7667, + "experience_temperature": 27.0967, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:30:09.163038+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.6, + "water_total": 709.0, + "average_temperature": 27.8333, + "experience_temperature": 27.5033, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:40:06.941321+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 82.8, + "water_total": 779.0, + "average_temperature": 27.7, + "experience_temperature": 27.21, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T19:50:09.939368+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 83.0, + "water_total": 860.0, + "average_temperature": 27.8333, + "experience_temperature": 24.769, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:00:06.592215+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 83.5, + "water_total": 924.0, + "average_temperature": 27.9, + "experience_temperature": 25.3714, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:10:07.805892+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 82.5, + "water_total": 983.0, + "average_temperature": 27.7667, + "experience_temperature": 27.6524, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:20:06.593622+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 82.7, + "water_total": 1040.0, + "average_temperature": 28.1, + "experience_temperature": 25.4114, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:30:06.121897+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 83.0, + "water_total": 1090.0, + "average_temperature": 27.9333, + "experience_temperature": 25.3048, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:40:06.918070+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.1, + "water_total": 1143.0, + "average_temperature": 27.8, + "experience_temperature": 27.37, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T20:50:06.425736+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.8, + "humidity": 83.5, + "water_total": 1194.0, + "average_temperature": 27.7333, + "experience_temperature": 26.9476, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:00:07.283294+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 83.2, + "water_total": 1244.0, + "average_temperature": 27.9, + "experience_temperature": 24.8757, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:10:06.255709+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.7, + "water_total": 1291.0, + "average_temperature": 27.7667, + "experience_temperature": 27.6567, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:20:06.448209+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.0, + "water_total": 1334.0, + "average_temperature": 27.7333, + "experience_temperature": 27.2833, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:30:06.405147+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 84.0, + "water_total": 1365.0, + "average_temperature": 27.7, + "experience_temperature": 25.2714, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:40:07.007965+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 1417.0, + "average_temperature": 27.8667, + "experience_temperature": 27.7167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T21:50:07.347339+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 85.0, + "water_total": 1468.0, + "average_temperature": 27.7667, + "experience_temperature": 27.7167, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:00:05.822126+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 84.7, + "water_total": 1521.0, + "average_temperature": 28.0333, + "experience_temperature": 25.7448, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:10:09.179810+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 85.1, + "water_total": 1574.0, + "average_temperature": 27.8667, + "experience_temperature": 25.6581, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:20:06.784860+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.1, + "humidity": 84.9, + "water_total": 1631.0, + "average_temperature": 27.8667, + "experience_temperature": 26.0538, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:30:07.056693+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 84.0, + "water_total": 1698.0, + "average_temperature": 27.7, + "experience_temperature": 27.8857, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:40:07.796113+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 83.6, + "water_total": 1757.0, + "average_temperature": 27.7667, + "experience_temperature": 27.4367, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T22:50:06.061448+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 83.7, + "water_total": 1822.0, + "average_temperature": 27.8, + "experience_temperature": 27.9257, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:00:06.145944+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 83.5, + "water_total": 1893.0, + "average_temperature": 27.8667, + "experience_temperature": 27.9524, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:10:06.891033+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.6, + "humidity": 82.7, + "water_total": 1953.0, + "average_temperature": 27.7, + "experience_temperature": 27.6257, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:20:06.592818+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 1963.0, + "average_temperature": 27.8333, + "experience_temperature": 27.6833, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:30:07.057783+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 84.6, + "water_total": 1972.0, + "average_temperature": 27.9, + "experience_temperature": 25.1557, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:40:06.839708+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.3, + "humidity": 83.0, + "water_total": 1986.0, + "average_temperature": 27.8667, + "experience_temperature": 24.8024, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-12T23:50:07.085644+07:00", + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 82.5, + "water_total": 1995.0, + "average_temperature": 27.8333, + "experience_temperature": 25.1048, + "chill_factor": 4.3571 + }, + { + "timestamp": "2026-06-13T00:00:06.189014+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 82.3, + "water_total": 2009.0, + "average_temperature": 27.8, + "experience_temperature": 25.2029, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T00:10:06.395533+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 82.3, + "water_total": 2009.0, + "average_temperature": 27.8, + "experience_temperature": 25.2029, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T00:20:06.826523+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.1, + "water_total": 2108.0, + "average_temperature": 27.7333, + "experience_temperature": 24.8748, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T00:30:06.784474+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.6, + "water_total": 2177.0, + "average_temperature": 27.8, + "experience_temperature": 25.0414, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T00:40:06.152585+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 83.6, + "water_total": 2239.0, + "average_temperature": 27.6, + "experience_temperature": 27.37, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T00:50:06.134741+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 83.6, + "water_total": 2303.0, + "average_temperature": 27.7, + "experience_temperature": 27.8914, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:00:06.299785+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 84.5, + "water_total": 2359.0, + "average_temperature": 27.7667, + "experience_temperature": 27.7167, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:10:08.236778+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 2428.0, + "average_temperature": 27.7667, + "experience_temperature": 25.5295, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:20:06.358566+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.5, + "water_total": 2486.0, + "average_temperature": 27.7, + "experience_temperature": 25.3429, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:30:06.438298+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 2537.0, + "average_temperature": 27.7667, + "experience_temperature": 25.5295, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:40:07.012142+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 84.7, + "water_total": 2572.0, + "average_temperature": 27.7333, + "experience_temperature": 25.6162, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T01:50:07.091632+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 2586.0, + "average_temperature": 27.7333, + "experience_temperature": 28.2648, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:00:06.805746+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.9, + "water_total": 2596.0, + "average_temperature": 27.7333, + "experience_temperature": 25.0348, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:10:06.428463+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.9, + "water_total": 2610.0, + "average_temperature": 27.8333, + "experience_temperature": 25.5562, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:20:07.309445+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 2680.0, + "average_temperature": 27.7333, + "experience_temperature": 25.4962, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:30:05.925886+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 83.7, + "water_total": 2756.0, + "average_temperature": 27.6667, + "experience_temperature": 27.4567, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:40:06.112730+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 83.6, + "water_total": 2813.0, + "average_temperature": 27.7, + "experience_temperature": 27.47, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T02:50:07.154039+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 83.6, + "water_total": 2872.0, + "average_temperature": 27.6667, + "experience_temperature": 27.0152, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:00:08.486532+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 83.7, + "water_total": 2930.0, + "average_temperature": 27.6333, + "experience_temperature": 27.4233, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:10:06.487565+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 84.6, + "water_total": 2980.0, + "average_temperature": 27.8, + "experience_temperature": 25.2414, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:20:07.115698+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 84.8, + "water_total": 3045.0, + "average_temperature": 27.7, + "experience_temperature": 27.71, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:30:06.669305+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 84.1, + "water_total": 3099.0, + "average_temperature": 27.6667, + "experience_temperature": 27.9581, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:40:08.003046+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 84.8, + "water_total": 3140.0, + "average_temperature": 27.6333, + "experience_temperature": 28.0648, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T03:50:06.659881+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.1, + "humidity": 85.3, + "water_total": 3186.0, + "average_temperature": 27.7333, + "experience_temperature": 26.1576, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:00:06.183539+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 3243.0, + "average_temperature": 27.7667, + "experience_temperature": 25.9095, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:10:06.383902+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 85.0, + "water_total": 3313.0, + "average_temperature": 27.8333, + "experience_temperature": 25.7762, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:20:06.220912+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 85.8, + "water_total": 3367.0, + "average_temperature": 27.7, + "experience_temperature": 27.91, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:30:06.112152+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 86.1, + "water_total": 3416.0, + "average_temperature": 27.6667, + "experience_temperature": 28.3581, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:40:07.345263+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.5, + "humidity": 86.2, + "water_total": 3449.0, + "average_temperature": 27.7, + "experience_temperature": 28.8329, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T04:50:06.311328+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.7, + "humidity": 86.5, + "water_total": 3458.0, + "average_temperature": 27.7333, + "experience_temperature": 28.0833, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:00:06.351013+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 86.4, + "water_total": 3471.0, + "average_temperature": 27.7333, + "experience_temperature": 25.9562, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:10:06.246203+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.1, + "humidity": 87.0, + "water_total": 3483.0, + "average_temperature": 27.9667, + "experience_temperature": 26.731, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:20:07.849123+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 86.6, + "water_total": 3565.0, + "average_temperature": 27.8, + "experience_temperature": 26.0629, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:30:07.168712+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 87.4, + "water_total": 3618.0, + "average_temperature": 27.6667, + "experience_temperature": 28.6181, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:40:06.654068+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 88.5, + "water_total": 3667.0, + "average_temperature": 27.9333, + "experience_temperature": 28.2619, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T05:50:06.351182+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.1, + "humidity": 86.0, + "water_total": 3720.0, + "average_temperature": 27.8, + "experience_temperature": 26.3643, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:00:06.688111+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 88.5, + "water_total": 3772.0, + "average_temperature": 27.8333, + "experience_temperature": 28.1619, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:10:07.924344+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 85.0, + "water_total": 3814.0, + "average_temperature": 27.5667, + "experience_temperature": 27.1952, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:20:06.484693+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 85.0, + "water_total": 3814.0, + "average_temperature": 27.5667, + "experience_temperature": 27.1952, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:30:06.665669+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 85.4, + "water_total": 3888.0, + "average_temperature": 27.6, + "experience_temperature": 28.1514, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:40:06.389704+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.6, + "humidity": 85.4, + "water_total": 3888.0, + "average_temperature": 27.6, + "experience_temperature": 28.1514, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T06:50:06.458844+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.9, + "humidity": 85.9, + "water_total": 3990.0, + "average_temperature": 27.7, + "experience_temperature": 27.0871, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:00:10.279961+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 0.8, + "humidity": 85.1, + "water_total": 4052.0, + "average_temperature": 27.5667, + "experience_temperature": 27.2152, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:10:06.637256+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 87.2, + "water_total": 4084.0, + "average_temperature": 27.7333, + "experience_temperature": 26.1162, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:20:06.254479+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.0, + "humidity": 86.3, + "water_total": 4122.0, + "average_temperature": 28.0333, + "experience_temperature": 27.079, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:30:06.482264+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.0, + "humidity": 85.7, + "water_total": 4166.0, + "average_temperature": 27.8333, + "experience_temperature": 26.759, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:40:06.971052+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 4216.0, + "average_temperature": 28.0, + "experience_temperature": 26.1429, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T07:50:07.255618+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 4266.0, + "average_temperature": 27.9667, + "experience_temperature": 26.2495, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:00:07.841623+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 85.8, + "water_total": 4317.0, + "average_temperature": 28.3, + "experience_temperature": 26.4029, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:10:06.447842+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.1, + "humidity": 84.7, + "water_total": 4372.0, + "average_temperature": 28.7, + "experience_temperature": 27.0043, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:20:06.871001+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.1, + "humidity": 84.7, + "water_total": 4372.0, + "average_temperature": 28.7, + "experience_temperature": 27.0043, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:30:06.975121+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 84.6, + "water_total": 4489.0, + "average_temperature": 28.6333, + "experience_temperature": 26.4962, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:40:06.755299+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.5, + "humidity": 82.7, + "water_total": 4557.0, + "average_temperature": 29.3, + "experience_temperature": 25.5186, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T08:50:06.478478+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.5, + "humidity": 81.6, + "water_total": 4618.0, + "average_temperature": 29.2, + "experience_temperature": 25.1986, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:00:06.495018+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 82.0, + "water_total": 4659.0, + "average_temperature": 28.9333, + "experience_temperature": 25.4333, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:10:06.895456+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 82.0, + "water_total": 4725.0, + "average_temperature": 29.1, + "experience_temperature": 26.0214, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:20:07.354988+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 82.4, + "water_total": 4837.0, + "average_temperature": 29.4, + "experience_temperature": 24.2943, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:30:08.267336+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 80.4, + "water_total": 4963.0, + "average_temperature": 29.4667, + "experience_temperature": 23.961, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:40:06.800351+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.9, + "humidity": 79.4, + "water_total": 5079.0, + "average_temperature": 29.7667, + "experience_temperature": 23.6395, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T09:50:07.393361+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 78.4, + "water_total": 5206.0, + "average_temperature": 29.7, + "experience_temperature": 24.2157, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:00:07.299024+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 79.0, + "water_total": 5270.0, + "average_temperature": 29.8333, + "experience_temperature": 24.0476, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:10:07.382072+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 79.6, + "water_total": 5299.0, + "average_temperature": 29.5667, + "experience_temperature": 24.3224, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:20:07.537159+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 79.2, + "water_total": 5416.0, + "average_temperature": 29.4667, + "experience_temperature": 24.1424, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:30:07.486418+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 78.2, + "water_total": 5552.0, + "average_temperature": 29.5667, + "experience_temperature": 23.621, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:40:08.183629+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 78.1, + "water_total": 5676.0, + "average_temperature": 30.0, + "experience_temperature": 24.0343, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T10:50:07.362506+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 77.1, + "water_total": 5810.0, + "average_temperature": 29.9333, + "experience_temperature": 23.7676, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:00:08.353856+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 75.8, + "water_total": 5928.0, + "average_temperature": 30.3333, + "experience_temperature": 23.9076, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:10:06.113938+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.2, + "humidity": 73.9, + "water_total": 5996.0, + "average_temperature": 31.3333, + "experience_temperature": 22.8419, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:20:06.128661+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 6079.0, + "average_temperature": 31.5333, + "experience_temperature": 23.7262, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:30:05.860589+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.0, + "humidity": 69.9, + "water_total": 6148.0, + "average_temperature": 31.6, + "experience_temperature": 23.1514, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:40:07.083718+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.1, + "humidity": 69.9, + "water_total": 6203.0, + "average_temperature": 31.9667, + "experience_temperature": 23.0967, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T11:50:06.741935+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 68.5, + "water_total": 6256.0, + "average_temperature": 31.9, + "experience_temperature": 21.0643, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:00:06.718913+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.4, + "humidity": 67.8, + "water_total": 6311.0, + "average_temperature": 32.0, + "experience_temperature": 21.4457, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:10:06.545986+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 67.8, + "water_total": 6361.0, + "average_temperature": 32.5333, + "experience_temperature": 21.5576, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:20:06.308353+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 67.8, + "water_total": 6361.0, + "average_temperature": 32.5333, + "experience_temperature": 21.5576, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:30:06.186268+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 66.2, + "water_total": 6460.0, + "average_temperature": 32.3667, + "experience_temperature": 21.9138, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:40:05.764295+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 65.8, + "water_total": 6514.0, + "average_temperature": 32.7333, + "experience_temperature": 22.2005, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T12:50:06.083254+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 65.8, + "water_total": 6514.0, + "average_temperature": 32.7333, + "experience_temperature": 22.2005, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:00:05.935119+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.7, + "humidity": 64.5, + "water_total": 6605.0, + "average_temperature": 32.7333, + "experience_temperature": 20.2548, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:10:05.981312+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.4, + "humidity": 64.2, + "water_total": 6658.0, + "average_temperature": 33.0333, + "experience_temperature": 21.759, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:20:06.258511+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 63.0, + "water_total": 6720.0, + "average_temperature": 33.0333, + "experience_temperature": 21.0976, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:30:07.018115+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 61.5, + "water_total": 6766.0, + "average_temperature": 33.0667, + "experience_temperature": 20.831, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:40:06.925223+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.4, + "humidity": 62.8, + "water_total": 6817.0, + "average_temperature": 33.0, + "experience_temperature": 21.4457, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T13:50:05.767055+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.7, + "humidity": 62.1, + "water_total": 6864.0, + "average_temperature": 33.0333, + "experience_temperature": 20.0748, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T14:10:07.530510+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.6, + "humidity": 60.5, + "water_total": 6954.0, + "average_temperature": 32.5667, + "experience_temperature": 19.7095, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T14:20:05.871721+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.6, + "humidity": 61.8, + "water_total": 7002.0, + "average_temperature": 33.0667, + "experience_temperature": 20.4695, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T14:30:05.869074+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 62.0, + "water_total": 7058.0, + "average_temperature": 32.6333, + "experience_temperature": 20.4976, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T14:40:06.179751+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.7, + "humidity": 62.0, + "water_total": 7106.0, + "average_temperature": 32.5667, + "experience_temperature": 19.5881, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T14:50:06.144486+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.6, + "humidity": 60.6, + "water_total": 7160.0, + "average_temperature": 32.8667, + "experience_temperature": 20.0295, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T15:10:05.771948+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.1, + "humidity": 62.4, + "water_total": 7260.0, + "average_temperature": 32.6667, + "experience_temperature": 22.2967, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T15:20:05.338886+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.7, + "humidity": 62.8, + "water_total": 7305.0, + "average_temperature": 32.4333, + "experience_temperature": 19.6148, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T15:30:05.926507+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.6, + "humidity": 62.5, + "water_total": 7360.0, + "average_temperature": 32.6333, + "experience_temperature": 20.1762, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T15:40:05.805544+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 62.8, + "water_total": 7407.0, + "average_temperature": 32.5, + "experience_temperature": 20.5243, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T15:50:05.603574+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 63.1, + "water_total": 7448.0, + "average_temperature": 32.5, + "experience_temperature": 20.5843, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T16:10:07.530397+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 63.2, + "water_total": 7572.0, + "average_temperature": 32.4333, + "experience_temperature": 20.5376, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T16:20:06.870198+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 63.4, + "water_total": 7635.0, + "average_temperature": 32.2667, + "experience_temperature": 21.2538, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T16:30:06.857297+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.5, + "humidity": 64.2, + "water_total": 7689.0, + "average_temperature": 32.2, + "experience_temperature": 20.5043, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T16:40:06.235841+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 63.4, + "water_total": 7731.0, + "average_temperature": 31.8667, + "experience_temperature": 20.8538, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T16:50:07.968026+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.3, + "humidity": 64.6, + "water_total": 7770.0, + "average_temperature": 31.7667, + "experience_temperature": 20.9938, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T17:10:06.852228+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.1, + "humidity": 65.1, + "water_total": 41.0, + "average_temperature": 31.4333, + "experience_temperature": 21.6033, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T17:20:06.236408+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.0, + "humidity": 65.6, + "water_total": 90.0, + "average_temperature": 31.2333, + "experience_temperature": 21.9248, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T17:30:07.974519+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.9, + "humidity": 66.2, + "water_total": 143.0, + "average_temperature": 30.9333, + "experience_temperature": 22.1662, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T17:40:06.053907+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.0, + "humidity": 66.9, + "water_total": 180.0, + "average_temperature": 30.8667, + "experience_temperature": 21.8181, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T17:50:06.967206+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.0, + "humidity": 66.7, + "water_total": 223.0, + "average_temperature": 30.6333, + "experience_temperature": 21.5448, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:00:08.436431+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.6, + "humidity": 67.8, + "water_total": 229.0, + "average_temperature": 30.3333, + "experience_temperature": 23.1505, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:10:06.489287+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 68.7, + "water_total": 234.0, + "average_temperature": 30.2, + "experience_temperature": 22.7757, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:20:05.332240+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.9, + "humidity": 68.5, + "water_total": 234.0, + "average_temperature": 30.2333, + "experience_temperature": 21.9262, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:30:06.474815+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 66.9, + "water_total": 234.0, + "average_temperature": 30.3, + "experience_temperature": 22.0943, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:40:06.617157+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.1, + "humidity": 67.7, + "water_total": 238.0, + "average_temperature": 30.4667, + "experience_temperature": 21.1567, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T18:50:06.734036+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 2.0, + "humidity": 68.4, + "water_total": 319.0, + "average_temperature": 30.4667, + "experience_temperature": 21.7181, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:00:07.645609+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 70.1, + "water_total": 404.0, + "average_temperature": 29.8667, + "experience_temperature": 22.301, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:10:05.850360+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 71.1, + "water_total": 464.0, + "average_temperature": 29.6333, + "experience_temperature": 22.689, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:20:06.565493+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.6, + "humidity": 73.2, + "water_total": 520.0, + "average_temperature": 29.3333, + "experience_temperature": 23.2305, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:30:07.043340+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.6, + "humidity": 73.5, + "water_total": 569.0, + "average_temperature": 29.2, + "experience_temperature": 23.1571, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:40:05.628726+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 73.4, + "water_total": 632.0, + "average_temperature": 29.2333, + "experience_temperature": 22.749, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T19:50:06.079147+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.6, + "humidity": 74.1, + "water_total": 685.0, + "average_temperature": 29.1, + "experience_temperature": 23.1771, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:00:06.421000+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.9, + "humidity": 75.3, + "water_total": 738.0, + "average_temperature": 29.0, + "experience_temperature": 22.0529, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:10:05.314786+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 75.9, + "water_total": 775.0, + "average_temperature": 29.0667, + "experience_temperature": 22.661, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:20:06.474473+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.8, + "humidity": 76.3, + "water_total": 815.0, + "average_temperature": 29.0, + "experience_temperature": 22.6743, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:30:05.869144+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.7, + "humidity": 78.0, + "water_total": 858.0, + "average_temperature": 28.9333, + "experience_temperature": 23.369, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:40:06.413296+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 78.8, + "water_total": 900.0, + "average_temperature": 28.8333, + "experience_temperature": 25.1148, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T20:50:05.765568+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 79.4, + "water_total": 952.0, + "average_temperature": 28.7333, + "experience_temperature": 25.1348, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:00:06.346174+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 80.4, + "water_total": 993.0, + "average_temperature": 28.5667, + "experience_temperature": 24.7467, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:10:06.067366+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 81.1, + "water_total": 1019.0, + "average_temperature": 28.3667, + "experience_temperature": 25.5295, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:20:06.698265+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 81.3, + "water_total": 1061.0, + "average_temperature": 28.2333, + "experience_temperature": 24.5933, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:30:08.626474+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 81.1, + "water_total": 1115.0, + "average_temperature": 28.2, + "experience_temperature": 24.9414, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:40:05.748777+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 81.0, + "water_total": 1184.0, + "average_temperature": 28.1333, + "experience_temperature": 24.8548, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T21:50:05.666009+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 82.8, + "water_total": 1252.0, + "average_temperature": 28.2, + "experience_temperature": 25.2814, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:00:06.202015+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.7, + "water_total": 1314.0, + "average_temperature": 27.8667, + "experience_temperature": 25.1281, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:10:06.044315+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.4, + "water_total": 1367.0, + "average_temperature": 28.0333, + "experience_temperature": 25.2348, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:20:05.721846+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 83.6, + "water_total": 1426.0, + "average_temperature": 28.0, + "experience_temperature": 24.82, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:30:05.722521+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.9, + "water_total": 1481.0, + "average_temperature": 28.0667, + "experience_temperature": 25.7895, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:40:05.945370+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 84.4, + "water_total": 1534.0, + "average_temperature": 27.9333, + "experience_temperature": 24.9133, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T22:50:05.788571+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 84.3, + "water_total": 1585.0, + "average_temperature": 27.7333, + "experience_temperature": 25.1148, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:00:06.004186+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.4, + "humidity": 84.8, + "water_total": 1590.0, + "average_temperature": 27.8667, + "experience_temperature": 24.9267, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:10:07.299137+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 82.8, + "water_total": 1660.0, + "average_temperature": 28.6667, + "experience_temperature": 26.1695, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:20:06.570109+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.3, + "humidity": 83.6, + "water_total": 1749.0, + "average_temperature": 27.9, + "experience_temperature": 25.1414, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:30:05.761411+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.5, + "humidity": 83.6, + "water_total": 1800.0, + "average_temperature": 27.9, + "experience_temperature": 24.2986, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:40:06.612256+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.5, + "water_total": 1800.0, + "average_temperature": 27.4667, + "experience_temperature": 25.1095, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-13T23:50:06.195034+07:00", + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 1800.0, + "average_temperature": 27.7, + "experience_temperature": 25.2629, + "chill_factor": 4.2143 + }, + { + "timestamp": "2026-06-14T00:00:06.124257+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 1800.0, + "average_temperature": 27.6, + "experience_temperature": 25.3343, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T00:10:06.198942+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.7, + "water_total": 1805.0, + "average_temperature": 27.8667, + "experience_temperature": 25.721, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T00:20:06.351924+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.2, + "water_total": 1888.0, + "average_temperature": 28.1, + "experience_temperature": 25.6543, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T00:30:05.898330+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.8, + "water_total": 1955.0, + "average_temperature": 27.7333, + "experience_temperature": 25.4076, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T00:40:07.364963+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.0, + "humidity": 83.4, + "water_total": 2006.0, + "average_temperature": 27.9333, + "experience_temperature": 26.5419, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T00:50:05.805544+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 82.7, + "water_total": 2057.0, + "average_temperature": 28.0, + "experience_temperature": 25.2471, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:00:06.391637+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.3, + "water_total": 2105.0, + "average_temperature": 27.9667, + "experience_temperature": 25.541, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:10:06.080857+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.9, + "water_total": 2153.0, + "average_temperature": 27.8, + "experience_temperature": 25.4943, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:20:07.416967+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.1, + "water_total": 2202.0, + "average_temperature": 27.7667, + "experience_temperature": 25.301, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:30:06.334418+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 82.9, + "water_total": 2248.0, + "average_temperature": 27.6333, + "experience_temperature": 24.9205, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:40:06.284629+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.5, + "water_total": 2271.0, + "average_temperature": 27.4, + "experience_temperature": 25.0143, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T01:50:06.365612+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.0, + "water_total": 2276.0, + "average_temperature": 27.4333, + "experience_temperature": 25.1476, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:00:05.932584+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.0, + "water_total": 2276.0, + "average_temperature": 27.4333, + "experience_temperature": 25.1476, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:10:06.284770+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.0, + "humidity": 82.6, + "water_total": 2276.0, + "average_temperature": 27.7667, + "experience_temperature": 26.2152, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:20:06.554876+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 82.3, + "water_total": 2343.0, + "average_temperature": 27.6667, + "experience_temperature": 25.241, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:30:07.264176+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 82.9, + "water_total": 2408.0, + "average_temperature": 27.6333, + "experience_temperature": 24.9205, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:40:06.776334+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 2458.0, + "average_temperature": 27.4667, + "experience_temperature": 25.201, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T02:50:06.045767+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 2492.0, + "average_temperature": 27.4, + "experience_temperature": 25.1343, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:00:08.285846+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.3, + "water_total": 2535.0, + "average_temperature": 27.4667, + "experience_temperature": 25.241, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:10:06.346933+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 2582.0, + "average_temperature": 27.3667, + "experience_temperature": 25.301, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:20:06.032873+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.8, + "water_total": 2627.0, + "average_temperature": 27.3333, + "experience_temperature": 27.8505, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:30:06.588646+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.1, + "humidity": 84.1, + "water_total": 2682.0, + "average_temperature": 27.4333, + "experience_temperature": 25.7748, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:40:05.873658+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.3, + "water_total": 2740.0, + "average_temperature": 27.2, + "experience_temperature": 27.6171, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T03:50:05.913487+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.7, + "water_total": 2792.0, + "average_temperature": 27.3333, + "experience_temperature": 27.8305, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:00:06.053865+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.7, + "humidity": 84.2, + "water_total": 2828.0, + "average_temperature": 27.2667, + "experience_temperature": 27.2567, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:10:05.980632+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.0, + "water_total": 2852.0, + "average_temperature": 27.2667, + "experience_temperature": 27.6238, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:20:06.232628+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 83.8, + "water_total": 2852.0, + "average_temperature": 27.1667, + "experience_temperature": 27.4838, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:30:06.534348+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.4, + "water_total": 2856.0, + "average_temperature": 27.2, + "experience_temperature": 27.8371, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:40:05.986286+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.0, + "water_total": 2856.0, + "average_temperature": 27.3, + "experience_temperature": 27.8571, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T04:50:07.651393+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.7, + "water_total": 2856.0, + "average_temperature": 27.3, + "experience_temperature": 27.7971, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:00:06.526855+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 2915.0, + "average_temperature": 27.3667, + "experience_temperature": 25.681, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:10:06.074688+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 84.3, + "water_total": 2969.0, + "average_temperature": 27.3333, + "experience_temperature": 27.7505, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:20:08.216561+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 83.8, + "water_total": 3019.0, + "average_temperature": 27.2333, + "experience_temperature": 27.5505, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:30:06.170991+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.0, + "water_total": 3064.0, + "average_temperature": 27.2667, + "experience_temperature": 25.181, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:40:06.425227+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.7, + "water_total": 3103.0, + "average_temperature": 27.2, + "experience_temperature": 27.8971, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T05:50:06.760754+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.9, + "humidity": 84.1, + "water_total": 3163.0, + "average_temperature": 27.2667, + "experience_temperature": 26.4224, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:00:06.827328+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.8, + "water_total": 3235.0, + "average_temperature": 27.2333, + "experience_temperature": 27.9505, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:10:07.215886+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 85.9, + "water_total": 3285.0, + "average_temperature": 27.2333, + "experience_temperature": 25.5276, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:20:06.052017+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.6, + "water_total": 3341.0, + "average_temperature": 27.2, + "experience_temperature": 27.8771, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:30:06.600480+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 86.0, + "water_total": 3399.0, + "average_temperature": 27.2333, + "experience_temperature": 27.9905, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:40:06.833289+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.1, + "water_total": 3445.0, + "average_temperature": 27.1333, + "experience_temperature": 27.7105, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T06:50:06.074588+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 0.6, + "humidity": 85.1, + "water_total": 3445.0, + "average_temperature": 27.1333, + "experience_temperature": 27.7105, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:00:07.332877+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.8, + "water_total": 3531.0, + "average_temperature": 27.3667, + "experience_temperature": 25.441, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:10:06.867809+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.7, + "water_total": 3578.0, + "average_temperature": 27.4, + "experience_temperature": 25.4543, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:20:06.638189+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 3618.0, + "average_temperature": 27.6333, + "experience_temperature": 25.5676, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:30:05.784265+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.9, + "water_total": 3667.0, + "average_temperature": 27.8333, + "experience_temperature": 25.7276, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:40:06.251227+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 81.8, + "water_total": 3719.0, + "average_temperature": 28.2667, + "experience_temperature": 25.741, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T07:50:06.122795+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.1, + "humidity": 82.6, + "water_total": 3776.0, + "average_temperature": 28.5333, + "experience_temperature": 26.5748, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:00:07.094512+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.6, + "humidity": 81.4, + "water_total": 3833.0, + "average_temperature": 28.8, + "experience_temperature": 24.5657, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:10:06.792860+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.8, + "humidity": 80.8, + "water_total": 3871.0, + "average_temperature": 28.8, + "experience_temperature": 23.6314, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:20:06.570775+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.4, + "humidity": 79.5, + "water_total": 3897.0, + "average_temperature": 29.0667, + "experience_temperature": 25.2667, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:30:06.115748+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.6, + "humidity": 77.5, + "water_total": 3935.0, + "average_temperature": 29.5, + "experience_temperature": 24.4857, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:40:06.639845+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 76.7, + "water_total": 3979.0, + "average_temperature": 29.5333, + "experience_temperature": 23.1376, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T08:50:07.962080+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 75.5, + "water_total": 4021.0, + "average_temperature": 30.0, + "experience_temperature": 24.1786, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:00:06.107219+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 74.5, + "water_total": 4086.0, + "average_temperature": 29.9667, + "experience_temperature": 25.5738, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:10:06.576347+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 73.9, + "water_total": 4148.0, + "average_temperature": 30.2, + "experience_temperature": 24.0586, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:20:06.166421+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 72.7, + "water_total": 4196.0, + "average_temperature": 30.7333, + "experience_temperature": 23.5376, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:30:06.785822+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 71.7, + "water_total": 4230.0, + "average_temperature": 30.9667, + "experience_temperature": 23.571, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:40:06.523613+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 72.6, + "water_total": 4290.0, + "average_temperature": 31.2, + "experience_temperature": 23.9843, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T09:50:06.461984+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 71.3, + "water_total": 4334.0, + "average_temperature": 31.2333, + "experience_temperature": 22.5362, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:00:06.415874+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 70.7, + "water_total": 4374.0, + "average_temperature": 31.4333, + "experience_temperature": 23.0233, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:10:06.150011+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 71.6, + "water_total": 4429.0, + "average_temperature": 31.8333, + "experience_temperature": 23.6033, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:20:06.339956+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 71.6, + "water_total": 4429.0, + "average_temperature": 31.8333, + "experience_temperature": 23.6033, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:30:07.124349+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.7, + "humidity": 65.9, + "water_total": 4524.0, + "average_temperature": 33.0333, + "experience_temperature": 21.2205, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:40:06.300219+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 64.0, + "water_total": 4574.0, + "average_temperature": 32.8667, + "experience_temperature": 21.081, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T10:50:06.377509+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.0, + "humidity": 64.0, + "water_total": 4636.0, + "average_temperature": 33.3667, + "experience_temperature": 19.9524, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:00:06.665314+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.9, + "humidity": 65.2, + "water_total": 4692.0, + "average_temperature": 33.5667, + "experience_temperature": 20.7995, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:10:06.889500+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.7, + "humidity": 63.3, + "water_total": 4746.0, + "average_temperature": 33.1667, + "experience_temperature": 20.8338, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:20:06.734383+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.2, + "humidity": 64.1, + "water_total": 4797.0, + "average_temperature": 33.3333, + "experience_temperature": 19.1248, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:30:06.454089+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 63.8, + "water_total": 4851.0, + "average_temperature": 33.1667, + "experience_temperature": 21.7481, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:40:06.189700+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 63.9, + "water_total": 4898.0, + "average_temperature": 33.0333, + "experience_temperature": 21.6348, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T11:50:07.233162+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 65.0, + "water_total": 4927.0, + "average_temperature": 32.5667, + "experience_temperature": 21.3881, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:00:07.252129+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.8, + "humidity": 64.5, + "water_total": 4991.0, + "average_temperature": 33.0667, + "experience_temperature": 20.5667, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:10:06.219387+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.7, + "humidity": 66.3, + "water_total": 5040.0, + "average_temperature": 32.8, + "experience_temperature": 21.0671, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:20:06.792875+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.2, + "humidity": 65.1, + "water_total": 5088.0, + "average_temperature": 33.3667, + "experience_temperature": 19.3581, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:30:06.809253+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 65.1, + "water_total": 5143.0, + "average_temperature": 33.5667, + "experience_temperature": 22.001, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:40:07.699729+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 65.0, + "water_total": 5198.0, + "average_temperature": 32.9333, + "experience_temperature": 21.7548, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T12:50:07.232749+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.0, + "humidity": 66.9, + "water_total": 5245.0, + "average_temperature": 33.3333, + "experience_temperature": 20.499, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:00:07.075291+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.9, + "humidity": 65.4, + "water_total": 5301.0, + "average_temperature": 33.3667, + "experience_temperature": 20.6395, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:10:09.339711+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.8, + "humidity": 65.9, + "water_total": 5355.0, + "average_temperature": 33.0333, + "experience_temperature": 20.8133, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:20:08.355634+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.0, + "humidity": 64.8, + "water_total": 5411.0, + "average_temperature": 33.2333, + "experience_temperature": 19.979, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:30:06.754856+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.1, + "humidity": 66.0, + "water_total": 5459.0, + "average_temperature": 33.5333, + "experience_temperature": 20.1119, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:40:06.944480+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 3.0, + "humidity": 65.0, + "water_total": 5514.0, + "average_temperature": 33.4667, + "experience_temperature": 20.2524, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T13:50:06.796788+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 65.8, + "water_total": 5567.0, + "average_temperature": 33.2667, + "experience_temperature": 22.2481, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T14:10:06.836384+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.8, + "humidity": 64.3, + "water_total": 5667.0, + "average_temperature": 33.4333, + "experience_temperature": 20.8933, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T14:20:06.363313+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.9, + "humidity": 63.5, + "water_total": 5717.0, + "average_temperature": 33.1667, + "experience_temperature": 20.0595, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T14:30:05.953021+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 65.0, + "water_total": 5766.0, + "average_temperature": 33.0333, + "experience_temperature": 21.8548, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T14:40:06.871021+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.4, + "humidity": 66.5, + "water_total": 5808.0, + "average_temperature": 32.5667, + "experience_temperature": 22.0952, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T14:50:07.219969+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 66.4, + "water_total": 5845.0, + "average_temperature": 32.3667, + "experience_temperature": 21.061, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T15:10:06.448623+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.7, + "humidity": 66.3, + "water_total": 5925.0, + "average_temperature": 32.7667, + "experience_temperature": 21.0338, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T15:20:06.851041+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.8, + "humidity": 66.2, + "water_total": 5971.0, + "average_temperature": 32.4, + "experience_temperature": 20.24, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T15:30:06.595949+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.8, + "humidity": 66.2, + "water_total": 6007.0, + "average_temperature": 32.3333, + "experience_temperature": 20.1733, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T15:40:07.702021+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 63.9, + "water_total": 6043.0, + "average_temperature": 32.6333, + "experience_temperature": 20.8276, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T15:50:06.509521+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.9, + "humidity": 65.1, + "water_total": 6091.0, + "average_temperature": 32.5667, + "experience_temperature": 19.7795, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T16:10:10.058169+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.5, + "humidity": 68.7, + "water_total": 6205.0, + "average_temperature": 32.0, + "experience_temperature": 21.5614, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T16:20:08.105198+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 69.6, + "water_total": 6299.0, + "average_temperature": 31.5667, + "experience_temperature": 22.5295, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T16:30:06.649930+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 69.5, + "water_total": 6373.0, + "average_temperature": 31.3, + "experience_temperature": 22.2429, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T16:40:06.965700+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.4, + "humidity": 70.7, + "water_total": 6423.0, + "average_temperature": 31.1667, + "experience_temperature": 21.5352, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T16:50:11.077482+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 68.0, + "water_total": 6469.0, + "average_temperature": 31.1667, + "experience_temperature": 20.181, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T17:10:06.566823+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 68.2, + "water_total": 27.0, + "average_temperature": 31.1, + "experience_temperature": 22.19, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T17:20:06.699770+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.6, + "humidity": 68.0, + "water_total": 71.0, + "average_temperature": 31.1333, + "experience_temperature": 20.1476, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T17:30:07.185106+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 69.0, + "water_total": 109.0, + "average_temperature": 31.1, + "experience_temperature": 21.9429, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T17:40:06.734363+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 69.3, + "water_total": 171.0, + "average_temperature": 30.9667, + "experience_temperature": 22.2767, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T17:50:07.099075+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 69.7, + "water_total": 214.0, + "average_temperature": 30.7, + "experience_temperature": 21.6829, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:00:05.539107+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.2, + "humidity": 72.0, + "water_total": 223.0, + "average_temperature": 30.2, + "experience_temperature": 21.6429, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:10:05.805408+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 72.9, + "water_total": 227.0, + "average_temperature": 30.2667, + "experience_temperature": 22.2967, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:20:10.644672+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 73.3, + "water_total": 227.0, + "average_temperature": 30.2, + "experience_temperature": 23.1243, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:30:06.276509+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.1, + "humidity": 73.1, + "water_total": 227.0, + "average_temperature": 30.1667, + "experience_temperature": 22.2367, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:40:05.905433+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 2.0, + "humidity": 74.0, + "water_total": 231.0, + "average_temperature": 30.2333, + "experience_temperature": 22.8905, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T18:50:06.073495+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 73.6, + "water_total": 315.0, + "average_temperature": 30.1, + "experience_temperature": 23.0843, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:00:05.728865+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 74.3, + "water_total": 392.0, + "average_temperature": 30.0333, + "experience_temperature": 23.9719, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:10:07.241222+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 74.3, + "water_total": 470.0, + "average_temperature": 29.9667, + "experience_temperature": 23.9052, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:20:06.248262+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 74.9, + "water_total": 549.0, + "average_temperature": 29.9, + "experience_temperature": 23.9586, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:30:05.718457+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 76.0, + "water_total": 617.0, + "average_temperature": 29.8333, + "experience_temperature": 24.1119, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:40:06.307944+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.6, + "humidity": 76.2, + "water_total": 690.0, + "average_temperature": 30.0, + "experience_temperature": 24.7257, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T19:50:07.425722+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.6, + "humidity": 76.8, + "water_total": 754.0, + "average_temperature": 29.8667, + "experience_temperature": 24.7124, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:00:05.600635+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.9, + "humidity": 78.2, + "water_total": 812.0, + "average_temperature": 29.7, + "experience_temperature": 23.6043, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:10:05.731371+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.8, + "humidity": 78.2, + "water_total": 861.0, + "average_temperature": 29.4667, + "experience_temperature": 23.7781, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:20:05.562743+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.5, + "humidity": 78.1, + "water_total": 896.0, + "average_temperature": 29.6333, + "experience_temperature": 25.1462, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:30:05.428384+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.5, + "humidity": 77.4, + "water_total": 948.0, + "average_temperature": 29.6, + "experience_temperature": 24.9729, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:40:05.860766+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.6, + "humidity": 78.1, + "water_total": 989.0, + "average_temperature": 29.5333, + "experience_temperature": 24.639, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T20:50:06.985843+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 79.4, + "water_total": 1024.0, + "average_temperature": 29.2667, + "experience_temperature": 24.2252, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:00:07.157976+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.7, + "humidity": 79.4, + "water_total": 1024.0, + "average_temperature": 29.2667, + "experience_temperature": 24.2252, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:10:06.454661+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.4, + "humidity": 79.0, + "water_total": 1094.0, + "average_temperature": 29.1, + "experience_temperature": 25.2, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:20:05.831904+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 80.9, + "water_total": 1123.0, + "average_temperature": 29.1, + "experience_temperature": 26.3943, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:30:05.858715+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 80.9, + "water_total": 1123.0, + "average_temperature": 29.1, + "experience_temperature": 26.3943, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:40:07.651355+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 81.2, + "water_total": 1192.0, + "average_temperature": 29.0, + "experience_temperature": 26.3543, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T21:50:05.987417+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 81.2, + "water_total": 1192.0, + "average_temperature": 29.0, + "experience_temperature": 26.3543, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:00:05.897713+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 82.4, + "water_total": 1266.0, + "average_temperature": 28.8667, + "experience_temperature": 26.0538, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:10:05.229032+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 81.9, + "water_total": 1300.0, + "average_temperature": 28.8, + "experience_temperature": 26.2943, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:20:06.894945+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 83.2, + "water_total": 1334.0, + "average_temperature": 28.6, + "experience_temperature": 25.9471, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:30:06.180680+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.4, + "humidity": 82.7, + "water_total": 1367.0, + "average_temperature": 28.6, + "experience_temperature": 25.44, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:40:05.795253+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 83.9, + "water_total": 1388.0, + "average_temperature": 28.5333, + "experience_temperature": 26.0205, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T22:50:05.626514+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.1, + "humidity": 85.6, + "water_total": 1443.0, + "average_temperature": 28.6667, + "experience_temperature": 27.3081, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:00:06.310230+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.2, + "water_total": 1465.0, + "average_temperature": 28.2667, + "experience_temperature": 26.221, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:10:05.799770+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 83.3, + "water_total": 1481.0, + "average_temperature": 28.3, + "experience_temperature": 26.0743, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:20:07.269425+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 83.2, + "water_total": 1512.0, + "average_temperature": 28.3, + "experience_temperature": 25.6471, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:30:05.826542+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.3, + "humidity": 83.9, + "water_total": 1557.0, + "average_temperature": 28.0667, + "experience_temperature": 25.5538, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:40:10.040941+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 84.6, + "water_total": 1596.0, + "average_temperature": 27.7333, + "experience_temperature": 25.7676, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-14T23:50:06.012112+07:00", + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 85.1, + "water_total": 1596.0, + "average_temperature": 27.9, + "experience_temperature": 26.0343, + "chill_factor": 4.0714 + }, + { + "timestamp": "2026-06-15T00:00:05.968334+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.5, + "water_total": 1596.0, + "average_temperature": 27.8, + "experience_temperature": 26.1857, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T00:10:07.840094+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 1596.0, + "average_temperature": 28.0, + "experience_temperature": 26.5057, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T00:20:06.555024+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.6, + "water_total": 1691.0, + "average_temperature": 27.6667, + "experience_temperature": 26.0724, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T00:30:05.336441+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.8, + "water_total": 1759.0, + "average_temperature": 27.6667, + "experience_temperature": 26.1124, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T00:40:05.382965+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.8, + "water_total": 1759.0, + "average_temperature": 27.6667, + "experience_temperature": 26.1124, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T00:50:06.767250+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 86.1, + "water_total": 1841.0, + "average_temperature": 27.4333, + "experience_temperature": 25.1533, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:00:05.910429+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 85.8, + "water_total": 1895.0, + "average_temperature": 27.3333, + "experience_temperature": 25.3862, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:10:05.609219+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.7, + "water_total": 1932.0, + "average_temperature": 27.4, + "experience_temperature": 25.8257, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:20:07.884859+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 85.9, + "water_total": 1979.0, + "average_temperature": 27.3, + "experience_temperature": 25.3729, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:30:06.980250+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 2023.0, + "average_temperature": 27.1333, + "experience_temperature": 25.639, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:40:06.852035+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.1, + "humidity": 86.3, + "water_total": 2044.0, + "average_temperature": 27.1, + "experience_temperature": 26.0386, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T01:50:06.989998+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 2044.0, + "average_temperature": 27.1, + "experience_temperature": 25.7257, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:00:05.499934+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 86.1, + "water_total": 2044.0, + "average_temperature": 27.0333, + "experience_temperature": 24.7533, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:10:05.944794+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 85.8, + "water_total": 2044.0, + "average_temperature": 27.2667, + "experience_temperature": 24.9267, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:20:05.901630+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 85.2, + "water_total": 2138.0, + "average_temperature": 27.6333, + "experience_temperature": 25.5662, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:30:05.815063+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 86.7, + "water_total": 2229.0, + "average_temperature": 27.0667, + "experience_temperature": 28.0495, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:40:05.446638+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 87.1, + "water_total": 2283.0, + "average_temperature": 27.1333, + "experience_temperature": 25.0533, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T02:50:05.796602+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 86.5, + "water_total": 2325.0, + "average_temperature": 27.2667, + "experience_temperature": 25.4595, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:00:05.440564+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 86.0, + "water_total": 2385.0, + "average_temperature": 27.1, + "experience_temperature": 25.1929, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:10:06.126781+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.2, + "water_total": 2446.0, + "average_temperature": 27.2, + "experience_temperature": 25.7257, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:20:06.101769+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 87.5, + "water_total": 2482.0, + "average_temperature": 27.2, + "experience_temperature": 25.2, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:30:06.604893+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 85.9, + "water_total": 2551.0, + "average_temperature": 27.2333, + "experience_temperature": 24.9133, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:40:06.353124+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 85.7, + "water_total": 2597.0, + "average_temperature": 26.9, + "experience_temperature": 27.6829, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T03:50:05.835401+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 86.2, + "water_total": 2645.0, + "average_temperature": 26.9667, + "experience_temperature": 27.8495, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:00:05.595490+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.9, + "humidity": 86.5, + "water_total": 2688.0, + "average_temperature": 27.0, + "experience_temperature": 26.7643, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:10:05.995523+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.7, + "humidity": 85.5, + "water_total": 2703.0, + "average_temperature": 26.9333, + "experience_temperature": 27.2833, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:20:06.056899+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.7, + "humidity": 85.7, + "water_total": 2703.0, + "average_temperature": 27.0, + "experience_temperature": 27.39, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:30:05.781264+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 85.4, + "water_total": 2703.0, + "average_temperature": 26.8667, + "experience_temperature": 27.5895, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:40:05.879632+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.0, + "humidity": 86.1, + "water_total": 2708.0, + "average_temperature": 27.0, + "experience_temperature": 26.2914, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T04:50:06.661423+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 85.2, + "water_total": 2708.0, + "average_temperature": 26.9333, + "experience_temperature": 27.6162, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:00:05.774602+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 86.3, + "water_total": 2708.0, + "average_temperature": 26.8667, + "experience_temperature": 27.7695, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:10:07.205059+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 85.0, + "water_total": 2708.0, + "average_temperature": 26.9333, + "experience_temperature": 27.5762, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:20:06.566953+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 85.3, + "water_total": 2786.0, + "average_temperature": 26.9333, + "experience_temperature": 27.6362, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:30:05.933309+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 84.8, + "water_total": 2867.0, + "average_temperature": 26.9, + "experience_temperature": 27.5029, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:40:06.404774+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 85.1, + "water_total": 2922.0, + "average_temperature": 27.1333, + "experience_temperature": 25.0462, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T05:50:06.458006+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 86.7, + "water_total": 2995.0, + "average_temperature": 27.1333, + "experience_temperature": 25.3662, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:00:05.806289+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 83.9, + "water_total": 3056.0, + "average_temperature": 26.7667, + "experience_temperature": 27.1895, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:10:05.856840+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.5, + "humidity": 85.3, + "water_total": 3106.0, + "average_temperature": 26.8, + "experience_temperature": 27.8957, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:20:05.464675+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 86.5, + "water_total": 3180.0, + "average_temperature": 26.8333, + "experience_temperature": 27.7762, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:30:06.038941+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.6, + "humidity": 86.2, + "water_total": 3212.0, + "average_temperature": 26.9333, + "experience_temperature": 27.8162, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:40:06.071207+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 3245.0, + "average_temperature": 26.9333, + "experience_temperature": 25.419, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T06:50:10.274323+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.8, + "humidity": 85.8, + "water_total": 3283.0, + "average_temperature": 26.9, + "experience_temperature": 26.9171, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:00:06.635503+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 0.8, + "humidity": 85.8, + "water_total": 3283.0, + "average_temperature": 26.9, + "experience_temperature": 26.9171, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:10:08.507537+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 85.6, + "water_total": 3360.0, + "average_temperature": 27.3, + "experience_temperature": 25.7057, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:20:06.502388+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 84.6, + "water_total": 3426.0, + "average_temperature": 27.5333, + "experience_temperature": 25.3462, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:30:07.753595+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 84.1, + "water_total": 3469.0, + "average_temperature": 27.8667, + "experience_temperature": 25.9724, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:40:06.143443+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 82.6, + "water_total": 3503.0, + "average_temperature": 28.4333, + "experience_temperature": 25.8462, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T07:50:06.175645+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.7, + "humidity": 82.7, + "water_total": 3563.0, + "average_temperature": 29.0, + "experience_temperature": 24.8614, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:00:06.127248+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 79.4, + "water_total": 3613.0, + "average_temperature": 29.0, + "experience_temperature": 23.8086, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:10:06.795997+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 79.4, + "water_total": 3613.0, + "average_temperature": 29.0, + "experience_temperature": 23.8086, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:20:07.679100+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 80.1, + "water_total": 3656.0, + "average_temperature": 29.4333, + "experience_temperature": 24.3819, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:30:07.680613+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 75.8, + "water_total": 3762.0, + "average_temperature": 29.7333, + "experience_temperature": 23.8219, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:40:06.876740+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 75.1, + "water_total": 3807.0, + "average_temperature": 29.9333, + "experience_temperature": 23.8819, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T08:50:06.971643+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 3848.0, + "average_temperature": 30.5333, + "experience_temperature": 23.1633, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:00:06.044443+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.0, + "humidity": 72.6, + "water_total": 3885.0, + "average_temperature": 30.9, + "experience_temperature": 23.5629, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:10:06.619122+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.4, + "humidity": 72.0, + "water_total": 3934.0, + "average_temperature": 30.9667, + "experience_temperature": 21.9381, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:20:07.026984+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 71.1, + "water_total": 3977.0, + "average_temperature": 30.9667, + "experience_temperature": 21.3652, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:30:07.494652+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 71.5, + "water_total": 4012.0, + "average_temperature": 31.0333, + "experience_temperature": 20.7262, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:40:06.603435+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.4, + "humidity": 71.5, + "water_total": 4049.0, + "average_temperature": 31.3667, + "experience_temperature": 22.2381, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T09:50:06.538054+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.4, + "humidity": 70.7, + "water_total": 4103.0, + "average_temperature": 31.6, + "experience_temperature": 22.3114, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:00:07.299221+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 70.0, + "water_total": 4165.0, + "average_temperature": 32.0, + "experience_temperature": 22.1786, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:10:06.318522+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 69.5, + "water_total": 4214.0, + "average_temperature": 31.9667, + "experience_temperature": 22.0452, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:20:06.407785+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 68.4, + "water_total": 4242.0, + "average_temperature": 31.7, + "experience_temperature": 20.7729, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:30:07.437805+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 68.8, + "water_total": 4292.0, + "average_temperature": 32.1667, + "experience_temperature": 22.1052, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:40:06.582615+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 68.7, + "water_total": 4333.0, + "average_temperature": 32.1667, + "experience_temperature": 21.2995, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T10:50:07.243395+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 67.7, + "water_total": 4372.0, + "average_temperature": 32.0667, + "experience_temperature": 20.9995, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:00:06.731500+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.9, + "humidity": 68.7, + "water_total": 4415.0, + "average_temperature": 32.7, + "experience_temperature": 21.0471, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:10:07.093843+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.8, + "humidity": 68.5, + "water_total": 4460.0, + "average_temperature": 32.4667, + "experience_temperature": 21.1667, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:20:07.133751+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 68.2, + "water_total": 4502.0, + "average_temperature": 32.3667, + "experience_temperature": 22.1852, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:30:06.231496+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.3, + "humidity": 68.0, + "water_total": 4544.0, + "average_temperature": 32.3, + "experience_temperature": 22.8643, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:40:08.544420+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 68.2, + "water_total": 4586.0, + "average_temperature": 32.0333, + "experience_temperature": 21.0662, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T11:50:08.355207+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.6, + "humidity": 67.4, + "water_total": 4627.0, + "average_temperature": 32.8667, + "experience_temperature": 22.1324, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:00:09.231232+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.8, + "humidity": 66.5, + "water_total": 4666.0, + "average_temperature": 32.4667, + "experience_temperature": 20.7667, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:10:06.503032+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.6, + "humidity": 66.7, + "water_total": 4718.0, + "average_temperature": 32.2333, + "experience_temperature": 21.359, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:20:06.099856+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.6, + "humidity": 66.7, + "water_total": 4718.0, + "average_temperature": 32.2333, + "experience_temperature": 21.359, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:30:11.016142+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.4, + "humidity": 65.9, + "water_total": 4797.0, + "average_temperature": 32.2, + "experience_temperature": 21.9514, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:40:06.304243+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.9, + "humidity": 64.7, + "water_total": 4838.0, + "average_temperature": 32.2, + "experience_temperature": 19.7471, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T12:50:06.828426+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 3.1, + "humidity": 64.4, + "water_total": 4883.0, + "average_temperature": 33.3667, + "experience_temperature": 20.0681, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:00:05.733442+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 3.0, + "humidity": 64.9, + "water_total": 4933.0, + "average_temperature": 33.2, + "experience_temperature": 20.3943, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:10:06.958287+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.7, + "humidity": 67.0, + "water_total": 4981.0, + "average_temperature": 32.4667, + "experience_temperature": 21.2595, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:20:09.646804+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 3.0, + "humidity": 70.3, + "water_total": 5022.0, + "average_temperature": 32.2667, + "experience_temperature": 20.541, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:30:06.639400+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 74.1, + "water_total": 5050.0, + "average_temperature": 31.4333, + "experience_temperature": 22.4319, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:40:08.266774+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 74.1, + "water_total": 5050.0, + "average_temperature": 31.4333, + "experience_temperature": 22.4319, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T13:50:07.576077+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.6, + "humidity": 75.5, + "water_total": 5113.0, + "average_temperature": 31.1667, + "experience_temperature": 22.0524, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T14:10:07.009143+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.6, + "humidity": 75.0, + "water_total": 5216.0, + "average_temperature": 30.3667, + "experience_temperature": 25.081, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T14:20:06.532805+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.1, + "humidity": 74.6, + "water_total": 5248.0, + "average_temperature": 30.1, + "experience_temperature": 22.77, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T14:30:06.655080+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.3, + "humidity": 75.2, + "water_total": 5281.0, + "average_temperature": 30.1, + "experience_temperature": 22.1043, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T14:40:07.784344+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.1, + "humidity": 75.5, + "water_total": 5310.0, + "average_temperature": 30.0333, + "experience_temperature": 22.8833, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T14:50:08.147371+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.0, + "humidity": 74.5, + "water_total": 5342.0, + "average_temperature": 30.0667, + "experience_temperature": 23.1095, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T15:10:07.193268+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.1, + "humidity": 75.4, + "water_total": 5403.0, + "average_temperature": 29.6333, + "experience_temperature": 22.4633, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T15:20:07.354715+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.3, + "humidity": 74.0, + "water_total": 5437.0, + "average_temperature": 29.5667, + "experience_temperature": 21.331, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T15:30:08.389432+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 73.7, + "water_total": 5466.0, + "average_temperature": 29.8, + "experience_temperature": 23.4686, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T15:40:08.727789+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.0, + "humidity": 71.5, + "water_total": 5515.0, + "average_temperature": 30.1333, + "experience_temperature": 22.5762, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T15:50:06.356875+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 72.2, + "water_total": 5537.0, + "average_temperature": 30.3333, + "experience_temperature": 20.9519, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T16:10:06.844318+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.5, + "humidity": 74.1, + "water_total": 5614.0, + "average_temperature": 30.6, + "experience_temperature": 21.5986, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T16:20:07.267903+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.6, + "humidity": 74.2, + "water_total": 5662.0, + "average_temperature": 30.4667, + "experience_temperature": 21.0924, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T16:30:06.656642+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.3, + "humidity": 73.8, + "water_total": 5727.0, + "average_temperature": 30.4333, + "experience_temperature": 22.1576, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T16:40:07.737250+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 75.7, + "water_total": 5795.0, + "average_temperature": 30.2, + "experience_temperature": 23.8757, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T16:50:10.326400+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.2, + "humidity": 75.6, + "water_total": 5846.0, + "average_temperature": 30.1333, + "experience_temperature": 22.6105, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T17:10:07.282952+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 76.7, + "water_total": 5973.0, + "average_temperature": 29.8667, + "experience_temperature": 23.7424, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T17:20:10.760038+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.4, + "humidity": 76.4, + "water_total": 6025.0, + "average_temperature": 29.6667, + "experience_temperature": 21.5181, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T17:30:06.298292+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.1, + "humidity": 76.8, + "water_total": 6070.0, + "average_temperature": 29.5667, + "experience_temperature": 22.6767, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T17:40:06.763024+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 78.4, + "water_total": 6113.0, + "average_temperature": 29.2667, + "experience_temperature": 23.8752, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T17:50:06.788814+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 76.3, + "water_total": 6169.0, + "average_temperature": 29.1667, + "experience_temperature": 22.9624, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:00:06.546490+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 77.7, + "water_total": 6222.0, + "average_temperature": 28.7667, + "experience_temperature": 22.8424, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:10:06.325739+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 2.0, + "humidity": 79.4, + "water_total": 6257.0, + "average_temperature": 28.3, + "experience_temperature": 22.3229, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:20:08.220090+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 79.6, + "water_total": 6297.0, + "average_temperature": 28.2333, + "experience_temperature": 23.0819, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:30:06.712151+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 81.1, + "water_total": 6332.0, + "average_temperature": 28.3, + "experience_temperature": 23.4486, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:40:06.257470+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 80.9, + "water_total": 6370.0, + "average_temperature": 28.2, + "experience_temperature": 23.3086, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T18:50:06.487340+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 80.7, + "water_total": 6404.0, + "average_temperature": 28.3333, + "experience_temperature": 23.4019, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:00:06.073702+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 80.9, + "water_total": 6430.0, + "average_temperature": 28.2667, + "experience_temperature": 22.9824, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:10:07.042992+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 82.1, + "water_total": 6483.0, + "average_temperature": 28.0667, + "experience_temperature": 23.0224, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:20:07.296489+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.9, + "humidity": 83.7, + "water_total": 6522.0, + "average_temperature": 27.8, + "experience_temperature": 23.0757, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:30:07.803900+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.6, + "humidity": 83.1, + "water_total": 6552.0, + "average_temperature": 27.9333, + "experience_temperature": 24.2676, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:40:06.472784+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.8, + "humidity": 83.6, + "water_total": 6592.0, + "average_temperature": 27.9667, + "experience_temperature": 23.6152, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T19:50:06.813463+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 84.1, + "water_total": 6627.0, + "average_temperature": 27.6, + "experience_temperature": 24.92, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:00:09.145958+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 83.4, + "water_total": 6679.0, + "average_temperature": 27.2667, + "experience_temperature": 24.4467, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:10:06.673016+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.5, + "humidity": 83.7, + "water_total": 6730.0, + "average_temperature": 27.2333, + "experience_temperature": 24.0805, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:20:06.978085+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 86.5, + "water_total": 6761.0, + "average_temperature": 26.7333, + "experience_temperature": 25.319, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:30:09.827758+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 86.1, + "water_total": 6811.0, + "average_temperature": 26.9333, + "experience_temperature": 25.0462, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:40:05.850705+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 87.0, + "water_total": 6868.0, + "average_temperature": 26.9333, + "experience_temperature": 24.8333, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T20:50:07.571666+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 87.3, + "water_total": 6920.0, + "average_temperature": 26.8333, + "experience_temperature": 25.1862, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:00:07.068264+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.4, + "humidity": 87.3, + "water_total": 6958.0, + "average_temperature": 26.7, + "experience_temperature": 24.66, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:10:06.812688+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 86.4, + "water_total": 7029.0, + "average_temperature": 27.4, + "experience_temperature": 25.5729, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:20:06.632617+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 87.6, + "water_total": 7100.0, + "average_temperature": 26.7, + "experience_temperature": 25.1129, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:30:06.377171+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.7, + "water_total": 7142.0, + "average_temperature": 26.7, + "experience_temperature": 25.3329, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:40:06.166609+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.8, + "water_total": 7182.0, + "average_temperature": 26.7, + "experience_temperature": 25.3529, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T21:50:06.541558+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.2, + "water_total": 7226.0, + "average_temperature": 26.8333, + "experience_temperature": 25.3662, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:00:06.666984+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 87.8, + "water_total": 7279.0, + "average_temperature": 26.9667, + "experience_temperature": 25.8124, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:10:07.108406+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 87.5, + "water_total": 7327.0, + "average_temperature": 26.7333, + "experience_temperature": 25.519, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:20:06.695159+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 87.5, + "water_total": 7375.0, + "average_temperature": 26.6, + "experience_temperature": 24.9929, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:30:07.108467+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 87.6, + "water_total": 7421.0, + "average_temperature": 26.5667, + "experience_temperature": 25.3724, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:40:08.511556+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.7, + "water_total": 7461.0, + "average_temperature": 26.5667, + "experience_temperature": 25.1995, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T22:50:07.282592+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 87.3, + "water_total": 7497.0, + "average_temperature": 26.7, + "experience_temperature": 25.0529, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:00:09.231823+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 87.7, + "water_total": 7576.0, + "average_temperature": 26.5667, + "experience_temperature": 25.3924, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:10:06.304325+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.0, + "water_total": 7602.0, + "average_temperature": 26.1, + "experience_temperature": 24.5929, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:20:06.826048+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.3, + "humidity": 88.9, + "water_total": 7602.0, + "average_temperature": 25.9667, + "experience_temperature": 24.6395, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:30:08.189401+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 7602.0, + "average_temperature": 25.9667, + "experience_temperature": 25.0324, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:40:06.638042+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 7602.0, + "average_temperature": 26.0333, + "experience_temperature": 25.139, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-15T23:50:06.496020+07:00", + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 7602.0, + "average_temperature": 25.9333, + "experience_temperature": 25.019, + "chill_factor": 3.9286 + }, + { + "timestamp": "2026-06-16T00:00:06.238078+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 7602.0, + "average_temperature": 25.9333, + "experience_temperature": 25.1705, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T00:10:07.388981+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 7602.0, + "average_temperature": 25.9333, + "experience_temperature": 25.1705, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T00:20:08.772935+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.4, + "water_total": 7687.0, + "average_temperature": 26.4333, + "experience_temperature": 25.3705, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T00:30:06.560896+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 87.6, + "water_total": 7742.0, + "average_temperature": 26.3333, + "experience_temperature": 24.9319, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T00:40:05.803472+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.5, + "water_total": 7798.0, + "average_temperature": 26.4, + "experience_temperature": 25.3571, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T00:50:05.508779+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.4, + "water_total": 7853.0, + "average_temperature": 26.5, + "experience_temperature": 25.6371, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:00:05.596366+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.4, + "water_total": 7853.0, + "average_temperature": 26.5, + "experience_temperature": 25.6371, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:10:05.535057+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 86.9, + "water_total": 7964.0, + "average_temperature": 26.5333, + "experience_temperature": 25.3705, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:20:06.635089+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.0, + "water_total": 8017.0, + "average_temperature": 26.3667, + "experience_temperature": 25.4238, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:30:05.379943+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 86.8, + "water_total": 8059.0, + "average_temperature": 26.4667, + "experience_temperature": 25.2838, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:40:05.702991+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 87.2, + "water_total": 8101.0, + "average_temperature": 26.8, + "experience_temperature": 25.3186, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T01:50:05.800167+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 86.7, + "water_total": 8178.0, + "average_temperature": 26.9, + "experience_temperature": 25.3186, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T02:00:05.499741+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.8, + "water_total": 8227.0, + "average_temperature": 26.9, + "experience_temperature": 25.9171, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T02:20:06.592373+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 87.4, + "water_total": 8342.0, + "average_temperature": 26.6667, + "experience_temperature": 25.2252, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T02:30:06.529112+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.7, + "water_total": 8377.0, + "average_temperature": 26.6333, + "experience_temperature": 25.6305, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T02:40:06.328748+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.7, + "water_total": 8419.0, + "average_temperature": 26.6333, + "experience_temperature": 25.6305, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T02:50:06.008936+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.5, + "water_total": 8475.0, + "average_temperature": 26.8, + "experience_temperature": 25.9571, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T03:00:07.189607+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 88.8, + "water_total": 8519.0, + "average_temperature": 26.6, + "experience_temperature": 25.4386, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T03:10:06.454310+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 88.5, + "water_total": 8558.0, + "average_temperature": 26.4333, + "experience_temperature": 25.2119, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T03:20:06.450590+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 8597.0, + "average_temperature": 26.5667, + "experience_temperature": 25.8038, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T03:50:06.285641+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 72.6, + "water_total": 8597.0, + "average_temperature": 30.9, + "experience_temperature": 24.9843, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T04:00:05.916158+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 72.6, + "water_total": 8597.0, + "average_temperature": 30.9, + "experience_temperature": 24.9843, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T04:20:06.332335+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.5, + "water_total": 8817.0, + "average_temperature": 25.8667, + "experience_temperature": 25.2238, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T04:30:06.333503+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 8817.0, + "average_temperature": 26.0, + "experience_temperature": 25.3371, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T04:40:06.294260+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 8817.0, + "average_temperature": 26.0333, + "experience_temperature": 25.4305, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T04:50:06.093407+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 8822.0, + "average_temperature": 25.8667, + "experience_temperature": 25.3038, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:00:06.825169+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 8822.0, + "average_temperature": 25.7667, + "experience_temperature": 25.2038, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:10:06.745421+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 8822.0, + "average_temperature": 26.1667, + "experience_temperature": 25.5838, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:20:06.777896+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 8874.0, + "average_temperature": 26.0333, + "experience_temperature": 25.3105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:30:05.971347+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.6, + "water_total": 8926.0, + "average_temperature": 25.7333, + "experience_temperature": 25.1105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:40:06.337952+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 89.5, + "water_total": 8951.0, + "average_temperature": 25.5333, + "experience_temperature": 24.5119, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T05:50:06.287862+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 8971.0, + "average_temperature": 25.7333, + "experience_temperature": 25.1905, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:00:05.757943+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 90.3, + "water_total": 8991.0, + "average_temperature": 25.6667, + "experience_temperature": 24.8052, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:10:08.123260+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 9023.0, + "average_temperature": 25.6333, + "experience_temperature": 25.0505, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:20:06.541216+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 9049.0, + "average_temperature": 25.4667, + "experience_temperature": 24.8638, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:30:06.138093+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 90.6, + "water_total": 9102.0, + "average_temperature": 26.1667, + "experience_temperature": 25.3652, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:40:07.618095+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 9198.0, + "average_temperature": 25.6333, + "experience_temperature": 24.8905, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T06:50:06.744988+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 9252.0, + "average_temperature": 25.8, + "experience_temperature": 25.2371, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:00:08.319481+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 9252.0, + "average_temperature": 25.8, + "experience_temperature": 25.2371, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:10:06.508028+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 91.2, + "water_total": 9339.0, + "average_temperature": 25.8333, + "experience_temperature": 25.5305, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:20:06.461139+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 89.9, + "water_total": 9381.0, + "average_temperature": 26.4333, + "experience_temperature": 25.4919, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:30:08.269907+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 88.2, + "water_total": 9460.0, + "average_temperature": 26.6333, + "experience_temperature": 25.3519, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:40:07.170245+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 87.3, + "water_total": 9518.0, + "average_temperature": 27.0, + "experience_temperature": 25.9171, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T07:50:06.147687+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 85.9, + "water_total": 9569.0, + "average_temperature": 27.2667, + "experience_temperature": 25.9038, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:00:06.437843+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 84.5, + "water_total": 9640.0, + "average_temperature": 27.8667, + "experience_temperature": 23.9524, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:10:06.870356+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 84.5, + "water_total": 9640.0, + "average_temperature": 27.8667, + "experience_temperature": 23.9524, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:20:08.386162+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.4, + "humidity": 83.0, + "water_total": 9754.0, + "average_temperature": 28.6333, + "experience_temperature": 25.9333, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:30:06.760363+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.3, + "humidity": 79.9, + "water_total": 9813.0, + "average_temperature": 29.0333, + "experience_temperature": 22.3062, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:40:06.185109+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.6, + "humidity": 79.1, + "water_total": 9849.0, + "average_temperature": 29.4333, + "experience_temperature": 25.1962, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T08:50:06.333062+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.0, + "humidity": 76.9, + "water_total": 9897.0, + "average_temperature": 29.6667, + "experience_temperature": 23.4752, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:00:06.542520+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 78.0, + "water_total": 9937.0, + "average_temperature": 29.8, + "experience_temperature": 24.2071, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:10:06.526211+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 78.4, + "water_total": 9982.0, + "average_temperature": 29.7667, + "experience_temperature": 24.6324, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:20:07.074058+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 78.2, + "water_total": 10039.0, + "average_temperature": 30.3, + "experience_temperature": 24.7471, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:30:07.337511+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 75.3, + "water_total": 10077.0, + "average_temperature": 30.7333, + "experience_temperature": 22.329, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:40:06.189160+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 73.3, + "water_total": 10136.0, + "average_temperature": 30.9333, + "experience_temperature": 21.7505, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T09:50:06.879712+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.0, + "humidity": 72.4, + "water_total": 10187.0, + "average_temperature": 31.0667, + "experience_temperature": 23.9752, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:00:06.101390+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 73.9, + "water_total": 10238.0, + "average_temperature": 31.4667, + "experience_temperature": 22.7824, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:10:06.191753+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 72.2, + "water_total": 10288.0, + "average_temperature": 31.5667, + "experience_temperature": 22.5424, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:20:06.858554+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.4, + "humidity": 71.2, + "water_total": 10318.0, + "average_temperature": 31.6333, + "experience_temperature": 22.7876, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:30:06.440015+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 69.7, + "water_total": 10371.0, + "average_temperature": 31.8333, + "experience_temperature": 22.309, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:40:06.211130+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 70.5, + "water_total": 10430.0, + "average_temperature": 31.9333, + "experience_temperature": 22.569, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T10:50:06.368071+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 70.7, + "water_total": 10486.0, + "average_temperature": 32.0667, + "experience_temperature": 22.7424, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:00:06.985145+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.9, + "humidity": 68.9, + "water_total": 10527.0, + "average_temperature": 32.4, + "experience_temperature": 21.2014, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:10:05.659416+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.8, + "humidity": 67.7, + "water_total": 10570.0, + "average_temperature": 32.0333, + "experience_temperature": 20.9733, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:20:05.303918+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 67.0, + "water_total": 10622.0, + "average_temperature": 32.6333, + "experience_temperature": 20.6762, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:30:05.663482+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.1, + "humidity": 66.9, + "water_total": 10672.0, + "average_temperature": 32.4, + "experience_temperature": 20.0443, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:40:05.448129+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.8, + "humidity": 65.5, + "water_total": 10708.0, + "average_temperature": 32.3333, + "experience_temperature": 20.8333, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T11:50:07.761155+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.8, + "humidity": 65.5, + "water_total": 10708.0, + "average_temperature": 32.3333, + "experience_temperature": 20.8333, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:00:08.035380+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 67.6, + "water_total": 10755.0, + "average_temperature": 32.6333, + "experience_temperature": 22.3105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:10:07.032912+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 66.6, + "water_total": 10848.0, + "average_temperature": 32.0667, + "experience_temperature": 20.0295, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:20:05.683848+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.2, + "humidity": 69.0, + "water_total": 10901.0, + "average_temperature": 32.4333, + "experience_temperature": 20.119, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:30:06.720403+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.2, + "water_total": 10947.0, + "average_temperature": 32.4333, + "experience_temperature": 20.7162, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:40:05.907240+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 67.3, + "water_total": 10990.0, + "average_temperature": 31.8333, + "experience_temperature": 21.829, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T12:50:06.385432+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.9, + "humidity": 66.5, + "water_total": 11034.0, + "average_temperature": 32.2, + "experience_temperature": 20.5214, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:00:05.485672+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.9, + "humidity": 67.5, + "water_total": 11085.0, + "average_temperature": 32.5333, + "experience_temperature": 21.0548, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:10:05.946734+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.6, + "water_total": 11122.0, + "average_temperature": 32.0, + "experience_temperature": 20.3629, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:20:06.004727+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 68.9, + "water_total": 11164.0, + "average_temperature": 31.8667, + "experience_temperature": 21.8038, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:30:06.160006+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.5, + "water_total": 11201.0, + "average_temperature": 31.9667, + "experience_temperature": 20.3095, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:40:05.360963+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.7, + "humidity": 69.6, + "water_total": 11242.0, + "average_temperature": 32.3, + "experience_temperature": 21.9986, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T13:50:05.682175+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 67.7, + "water_total": 11286.0, + "average_temperature": 32.3333, + "experience_temperature": 20.5162, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T14:10:06.406855+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.8, + "water_total": 11386.0, + "average_temperature": 32.8333, + "experience_temperature": 21.2362, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T14:20:05.418446+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.8, + "water_total": 11386.0, + "average_temperature": 32.8333, + "experience_temperature": 21.2362, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T14:30:08.167853+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 69.1, + "water_total": 11478.0, + "average_temperature": 32.1333, + "experience_temperature": 22.1105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T14:40:06.827856+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 69.1, + "water_total": 11478.0, + "average_temperature": 32.1333, + "experience_temperature": 22.1105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T14:50:05.806026+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.6, + "humidity": 67.3, + "water_total": 11527.0, + "average_temperature": 32.5, + "experience_temperature": 22.1171, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T15:10:05.992847+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.0, + "humidity": 68.5, + "water_total": 11653.0, + "average_temperature": 32.4333, + "experience_temperature": 20.7762, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T15:20:05.798989+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.2, + "humidity": 66.8, + "water_total": 11704.0, + "average_temperature": 32.4, + "experience_temperature": 19.6457, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T15:30:06.347114+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.7, + "humidity": 67.3, + "water_total": 11757.0, + "average_temperature": 32.3333, + "experience_temperature": 21.5719, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T15:40:05.732054+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.2, + "humidity": 65.9, + "water_total": 11802.0, + "average_temperature": 32.1667, + "experience_temperature": 19.2324, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T15:50:06.158473+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 68.4, + "water_total": 11882.0, + "average_temperature": 31.8333, + "experience_temperature": 22.049, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T16:10:05.776096+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.8, + "humidity": 67.2, + "water_total": 11985.0, + "average_temperature": 32.2, + "experience_temperature": 21.04, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T16:20:07.643769+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 3.7, + "humidity": 67.0, + "water_total": 12048.0, + "average_temperature": 31.9333, + "experience_temperature": 17.3262, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T16:30:06.471860+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 67.7, + "water_total": 12104.0, + "average_temperature": 31.8667, + "experience_temperature": 21.9424, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T16:40:05.537446+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.7, + "humidity": 67.0, + "water_total": 12158.0, + "average_temperature": 31.4667, + "experience_temperature": 20.6452, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T16:50:06.195848+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.4, + "humidity": 67.5, + "water_total": 12204.0, + "average_temperature": 31.3667, + "experience_temperature": 21.781, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T17:10:06.056755+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 67.6, + "water_total": 37.0, + "average_temperature": 30.8333, + "experience_temperature": 20.889, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T17:20:06.111020+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 68.8, + "water_total": 77.0, + "average_temperature": 30.8333, + "experience_temperature": 21.129, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T17:30:05.845097+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.5, + "humidity": 69.8, + "water_total": 108.0, + "average_temperature": 30.4667, + "experience_temperature": 20.9624, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T17:40:05.391769+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.4, + "humidity": 72.6, + "water_total": 147.0, + "average_temperature": 30.5, + "experience_temperature": 21.9343, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T17:50:06.985225+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.2, + "humidity": 73.1, + "water_total": 228.0, + "average_temperature": 30.1, + "experience_temperature": 22.3914, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:00:06.831115+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.3, + "humidity": 72.9, + "water_total": 272.0, + "average_temperature": 29.8667, + "experience_temperature": 21.7395, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:10:06.061529+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.3, + "humidity": 72.9, + "water_total": 272.0, + "average_temperature": 29.8667, + "experience_temperature": 21.7395, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:20:06.309675+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.0, + "humidity": 73.1, + "water_total": 342.0, + "average_temperature": 29.7, + "experience_temperature": 22.7486, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:30:05.483261+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 2.1, + "humidity": 73.7, + "water_total": 373.0, + "average_temperature": 29.6333, + "experience_temperature": 22.4233, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:40:06.232112+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 75.5, + "water_total": 408.0, + "average_temperature": 29.3, + "experience_temperature": 23.9643, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T18:50:05.117302+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 75.7, + "water_total": 445.0, + "average_temperature": 29.2333, + "experience_temperature": 23.9376, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:00:06.351177+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 76.2, + "water_total": 494.0, + "average_temperature": 29.1333, + "experience_temperature": 23.9376, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:10:05.838321+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 76.2, + "water_total": 494.0, + "average_temperature": 29.1333, + "experience_temperature": 23.9376, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:20:05.897129+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 76.7, + "water_total": 571.0, + "average_temperature": 29.1333, + "experience_temperature": 23.2805, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:30:07.857427+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 78.1, + "water_total": 611.0, + "average_temperature": 29.0, + "experience_temperature": 24.1843, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:40:05.532138+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 77.9, + "water_total": 650.0, + "average_temperature": 28.7667, + "experience_temperature": 23.5324, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T19:50:05.868808+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 78.9, + "water_total": 685.0, + "average_temperature": 28.8, + "experience_temperature": 23.7657, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:00:07.191177+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 79.8, + "water_total": 718.0, + "average_temperature": 28.5333, + "experience_temperature": 23.679, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:10:09.198404+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.6, + "humidity": 80.5, + "water_total": 757.0, + "average_temperature": 28.3333, + "experience_temperature": 24.3762, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:20:05.477366+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.0, + "water_total": 800.0, + "average_temperature": 28.2667, + "experience_temperature": 23.6524, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:30:06.174209+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 79.4, + "water_total": 841.0, + "average_temperature": 27.9333, + "experience_temperature": 22.6205, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:40:07.324730+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 79.9, + "water_total": 868.0, + "average_temperature": 28.0, + "experience_temperature": 23.5443, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T20:50:06.122495+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.1, + "water_total": 890.0, + "average_temperature": 27.8, + "experience_temperature": 23.2057, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:00:06.136383+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.0, + "water_total": 911.0, + "average_temperature": 27.7667, + "experience_temperature": 23.1524, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:10:06.368749+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.7, + "humidity": 80.8, + "water_total": 938.0, + "average_temperature": 27.7333, + "experience_temperature": 23.4576, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:20:07.473794+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.7, + "water_total": 972.0, + "average_temperature": 27.9, + "experience_temperature": 23.4257, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:30:05.251333+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.7, + "water_total": 972.0, + "average_temperature": 27.9, + "experience_temperature": 23.4257, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:40:06.054440+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.6, + "humidity": 80.3, + "water_total": 1047.0, + "average_temperature": 27.8, + "experience_temperature": 23.8029, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T21:50:06.780192+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 81.6, + "water_total": 1069.0, + "average_temperature": 27.4333, + "experience_temperature": 22.5605, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:00:06.105142+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.9, + "humidity": 81.6, + "water_total": 1069.0, + "average_temperature": 27.4333, + "experience_temperature": 22.5605, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:10:06.645327+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 81.9, + "water_total": 1135.0, + "average_temperature": 27.6667, + "experience_temperature": 23.2324, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:20:06.842407+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.6, + "humidity": 82.5, + "water_total": 1201.0, + "average_temperature": 27.3667, + "experience_temperature": 23.8095, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:30:06.096419+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 83.2, + "water_total": 1258.0, + "average_temperature": 27.3, + "experience_temperature": 25.0186, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:40:07.634773+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.8, + "humidity": 82.9, + "water_total": 1321.0, + "average_temperature": 27.3333, + "experience_temperature": 23.099, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T22:50:06.192785+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 81.8, + "water_total": 1382.0, + "average_temperature": 27.1667, + "experience_temperature": 24.6052, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:00:06.445809+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 81.8, + "water_total": 1382.0, + "average_temperature": 27.1667, + "experience_temperature": 24.6052, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:10:06.254540+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 82.6, + "water_total": 1479.0, + "average_temperature": 27.1333, + "experience_temperature": 25.1105, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:20:06.881222+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.3, + "humidity": 82.3, + "water_total": 1530.0, + "average_temperature": 27.0333, + "experience_temperature": 24.5719, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:30:06.685303+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 83.3, + "water_total": 1561.0, + "average_temperature": 26.8667, + "experience_temperature": 24.9838, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:40:06.376661+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.2, + "humidity": 83.5, + "water_total": 1561.0, + "average_temperature": 26.7333, + "experience_temperature": 24.8905, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-16T23:50:06.230833+07:00", + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.1, + "humidity": 83.7, + "water_total": 1561.0, + "average_temperature": 26.8333, + "experience_temperature": 25.409, + "chill_factor": 3.7857 + }, + { + "timestamp": "2026-06-17T00:00:06.570128+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 83.6, + "water_total": 1561.0, + "average_temperature": 26.8667, + "experience_temperature": 24.851, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T00:10:06.221074+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 84.3, + "water_total": 1561.0, + "average_temperature": 27.1667, + "experience_temperature": 24.9267, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T00:20:07.238441+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 83.3, + "water_total": 1641.0, + "average_temperature": 27.0, + "experience_temperature": 24.56, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T00:30:06.585269+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 84.0, + "water_total": 1715.0, + "average_temperature": 26.6333, + "experience_temperature": 25.0619, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T00:40:06.378509+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 84.7, + "water_total": 1748.0, + "average_temperature": 26.3333, + "experience_temperature": 24.1733, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T00:50:07.040389+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 84.7, + "water_total": 1776.0, + "average_temperature": 26.3333, + "experience_temperature": 24.5376, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:00:07.279092+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 85.2, + "water_total": 1824.0, + "average_temperature": 26.5, + "experience_temperature": 25.1686, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:10:08.847479+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 85.7, + "water_total": 1888.0, + "average_temperature": 26.4333, + "experience_temperature": 24.8376, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:20:06.363243+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 86.0, + "water_total": 1939.0, + "average_temperature": 26.1, + "experience_temperature": 24.5643, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:30:07.062919+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 85.3, + "water_total": 1995.0, + "average_temperature": 26.2667, + "experience_temperature": 24.9552, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:40:06.360265+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 85.9, + "water_total": 2044.0, + "average_temperature": 26.4333, + "experience_temperature": 25.2419, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T01:50:06.881479+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.5, + "water_total": 2083.0, + "average_temperature": 26.4, + "experience_temperature": 25.5286, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T02:00:06.127683+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 86.6, + "water_total": 2117.0, + "average_temperature": 26.3667, + "experience_temperature": 24.951, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T02:10:06.475837+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 84.1, + "water_total": 2165.0, + "average_temperature": 26.4333, + "experience_temperature": 24.5176, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T02:20:06.440138+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 84.8, + "water_total": 2229.0, + "average_temperature": 26.1333, + "experience_temperature": 25.0862, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T02:40:06.147401+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 86.4, + "water_total": 2290.0, + "average_temperature": 25.7667, + "experience_temperature": 24.6752, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T02:50:06.455296+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.2, + "water_total": 2316.0, + "average_temperature": 25.7667, + "experience_temperature": 24.8352, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:00:06.462618+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 86.7, + "water_total": 2347.0, + "average_temperature": 25.5667, + "experience_temperature": 23.8067, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:10:06.627923+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.1, + "water_total": 2374.0, + "average_temperature": 25.5667, + "experience_temperature": 24.251, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:20:06.602813+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.0, + "humidity": 87.6, + "water_total": 2421.0, + "average_temperature": 25.6333, + "experience_temperature": 25.5105, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:30:05.637444+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.5, + "humidity": 88.7, + "water_total": 2473.0, + "average_temperature": 25.5333, + "experience_temperature": 23.809, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:40:05.953748+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 2516.0, + "average_temperature": 25.1667, + "experience_temperature": 24.6752, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T03:50:05.761341+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 88.6, + "water_total": 2542.0, + "average_temperature": 25.1667, + "experience_temperature": 24.151, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:00:05.565912+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.6, + "water_total": 2568.0, + "average_temperature": 25.2333, + "experience_temperature": 24.3819, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:10:05.487731+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.0, + "water_total": 2594.0, + "average_temperature": 25.2, + "experience_temperature": 24.2286, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:20:05.665866+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 86.4, + "water_total": 2619.0, + "average_temperature": 25.1667, + "experience_temperature": 23.711, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:30:05.808753+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.2, + "water_total": 2656.0, + "average_temperature": 25.3, + "experience_temperature": 24.0043, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:40:08.006590+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 86.9, + "water_total": 2684.0, + "average_temperature": 25.1667, + "experience_temperature": 24.5395, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T04:50:05.477881+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.4, + "water_total": 2714.0, + "average_temperature": 25.2333, + "experience_temperature": 24.3419, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:00:06.803023+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 87.1, + "water_total": 2750.0, + "average_temperature": 25.1333, + "experience_temperature": 23.4533, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:10:07.024476+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.9, + "water_total": 2758.0, + "average_temperature": 24.9333, + "experience_temperature": 23.7776, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:20:06.180723+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 2785.0, + "average_temperature": 24.9333, + "experience_temperature": 23.7819, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:30:07.075398+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.3, + "water_total": 2799.0, + "average_temperature": 24.9333, + "experience_temperature": 24.0219, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:40:07.670334+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 0.7, + "humidity": 87.2, + "water_total": 2815.0, + "average_temperature": 24.8333, + "experience_temperature": 25.7233, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T05:50:08.015508+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 88.5, + "water_total": 2847.0, + "average_temperature": 25.0, + "experience_temperature": 23.9643, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:00:06.807200+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 87.0, + "water_total": 2883.0, + "average_temperature": 25.4, + "experience_temperature": 24.4286, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:10:07.193668+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 88.0, + "water_total": 2904.0, + "average_temperature": 25.0333, + "experience_temperature": 24.2619, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:20:06.568484+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 2935.0, + "average_temperature": 25.0667, + "experience_temperature": 23.731, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:30:06.880519+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 2935.0, + "average_temperature": 25.0667, + "experience_temperature": 23.731, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:40:06.606925+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 87.3, + "water_total": 3038.0, + "average_temperature": 24.8667, + "experience_temperature": 23.591, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T06:50:07.228542+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.4, + "humidity": 87.4, + "water_total": 3055.0, + "average_temperature": 24.9667, + "experience_temperature": 23.3467, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:00:05.907135+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 87.2, + "water_total": 3082.0, + "average_temperature": 25.3, + "experience_temperature": 24.7329, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:10:05.395072+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 87.2, + "water_total": 3082.0, + "average_temperature": 25.3, + "experience_temperature": 24.7329, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:20:06.128521+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 87.3, + "water_total": 3151.0, + "average_temperature": 25.8333, + "experience_temperature": 25.2862, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:30:05.899044+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.2, + "humidity": 86.8, + "water_total": 3188.0, + "average_temperature": 26.2667, + "experience_temperature": 25.2552, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:40:05.653271+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 86.2, + "water_total": 3230.0, + "average_temperature": 26.5333, + "experience_temperature": 25.0376, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T07:50:05.625300+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 85.4, + "water_total": 3287.0, + "average_temperature": 27.1, + "experience_temperature": 26.1729, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:00:05.984694+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 85.4, + "water_total": 3287.0, + "average_temperature": 27.1, + "experience_temperature": 26.1729, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:10:05.853100+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.1, + "humidity": 83.9, + "water_total": 3329.0, + "average_temperature": 27.2667, + "experience_temperature": 26.0395, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:20:08.281177+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 80.6, + "water_total": 3445.0, + "average_temperature": 28.3667, + "experience_temperature": 24.2938, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:30:06.145676+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.3, + "humidity": 77.6, + "water_total": 3503.0, + "average_temperature": 28.7, + "experience_temperature": 25.4843, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:40:05.840813+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 75.9, + "water_total": 3551.0, + "average_temperature": 29.2667, + "experience_temperature": 23.5252, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T08:50:10.091734+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 74.1, + "water_total": 3598.0, + "average_temperature": 29.5667, + "experience_temperature": 23.4652, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:00:06.068311+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 73.6, + "water_total": 3650.0, + "average_temperature": 29.8333, + "experience_temperature": 23.2676, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:10:06.714259+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 72.7, + "water_total": 3701.0, + "average_temperature": 30.1333, + "experience_temperature": 24.1162, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:20:05.684828+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.2, + "humidity": 73.8, + "water_total": 3745.0, + "average_temperature": 30.3333, + "experience_temperature": 23.079, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:30:08.019148+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 70.5, + "water_total": 3795.0, + "average_temperature": 30.3, + "experience_temperature": 22.75, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:40:07.262473+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.3, + "humidity": 70.1, + "water_total": 3843.0, + "average_temperature": 30.5333, + "experience_temperature": 22.1748, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T09:50:07.342592+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.4, + "humidity": 70.4, + "water_total": 3899.0, + "average_temperature": 31.3, + "experience_temperature": 22.6371, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:00:06.762163+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 69.0, + "water_total": 3960.0, + "average_temperature": 31.3667, + "experience_temperature": 22.0595, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:10:06.673088+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 68.4, + "water_total": 4013.0, + "average_temperature": 31.3333, + "experience_temperature": 21.9062, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:20:11.251806+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 67.4, + "water_total": 4057.0, + "average_temperature": 31.1333, + "experience_temperature": 21.5062, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:30:06.363938+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 66.6, + "water_total": 4098.0, + "average_temperature": 31.5333, + "experience_temperature": 21.7462, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:40:06.399430+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 64.2, + "water_total": 4153.0, + "average_temperature": 32.3667, + "experience_temperature": 21.7352, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T10:50:06.060009+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.8, + "humidity": 64.3, + "water_total": 4208.0, + "average_temperature": 32.0, + "experience_temperature": 20.66, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:00:06.760082+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 63.7, + "water_total": 4265.0, + "average_temperature": 32.2, + "experience_temperature": 21.4686, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:10:06.773762+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 64.8, + "water_total": 4305.0, + "average_temperature": 31.6333, + "experience_temperature": 21.1219, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:20:06.432495+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.7, + "humidity": 62.5, + "water_total": 4363.0, + "average_temperature": 32.0, + "experience_temperature": 20.6643, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:30:06.676306+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.9, + "humidity": 62.5, + "water_total": 4400.0, + "average_temperature": 32.1333, + "experience_temperature": 20.069, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:40:06.012053+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.7, + "humidity": 61.7, + "water_total": 4458.0, + "average_temperature": 32.2667, + "experience_temperature": 20.771, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T11:50:05.779246+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 64.4, + "water_total": 4502.0, + "average_temperature": 32.1, + "experience_temperature": 21.5086, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:00:05.711295+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.9, + "humidity": 64.5, + "water_total": 4544.0, + "average_temperature": 32.1333, + "experience_temperature": 20.469, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:10:06.998067+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 65.2, + "water_total": 4585.0, + "average_temperature": 31.8333, + "experience_temperature": 21.7662, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:20:06.333697+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 62.2, + "water_total": 4622.0, + "average_temperature": 32.4333, + "experience_temperature": 21.4019, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:30:06.978108+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.9, + "humidity": 63.3, + "water_total": 4677.0, + "average_temperature": 32.1, + "experience_temperature": 20.1957, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:40:06.038899+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 63.3, + "water_total": 4727.0, + "average_temperature": 31.8667, + "experience_temperature": 21.0552, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T12:50:07.779413+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 3.1, + "humidity": 61.5, + "water_total": 4768.0, + "average_temperature": 32.4, + "experience_temperature": 19.4071, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:00:08.277543+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.2, + "humidity": 61.7, + "water_total": 4823.0, + "average_temperature": 32.1667, + "experience_temperature": 22.4924, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:10:06.085024+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 61.8, + "water_total": 4860.0, + "average_temperature": 32.2667, + "experience_temperature": 21.1552, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:20:07.560673+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 61.8, + "water_total": 4860.0, + "average_temperature": 32.2667, + "experience_temperature": 21.1552, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:30:06.917921+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.8, + "humidity": 61.0, + "water_total": 4962.0, + "average_temperature": 32.2333, + "experience_temperature": 20.2333, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:40:06.387195+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.7, + "humidity": 62.2, + "water_total": 5005.0, + "average_temperature": 32.1667, + "experience_temperature": 20.771, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T13:50:06.524222+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.9, + "humidity": 61.4, + "water_total": 5043.0, + "average_temperature": 32.4333, + "experience_temperature": 20.149, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T14:10:07.217180+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 58.5, + "water_total": 5130.0, + "average_temperature": 31.9333, + "experience_temperature": 20.5262, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T14:20:09.558069+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 3.0, + "humidity": 59.1, + "water_total": 5167.0, + "average_temperature": 32.1, + "experience_temperature": 18.9914, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T14:30:06.040903+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 3.0, + "humidity": 59.1, + "water_total": 5199.0, + "average_temperature": 32.2667, + "experience_temperature": 19.1581, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T14:40:06.445868+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 3.0, + "humidity": 61.0, + "water_total": 5256.0, + "average_temperature": 32.2667, + "experience_temperature": 19.5381, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T14:50:10.333932+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 3.0, + "humidity": 61.0, + "water_total": 5256.0, + "average_temperature": 32.2667, + "experience_temperature": 19.5381, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T15:10:06.442013+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.4, + "humidity": 60.4, + "water_total": 5292.0, + "average_temperature": 32.0, + "experience_temperature": 21.3371, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T15:20:06.531921+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 61.7, + "water_total": 5417.0, + "average_temperature": 32.1667, + "experience_temperature": 21.3995, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T15:30:06.182811+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 62.2, + "water_total": 5477.0, + "average_temperature": 31.6667, + "experience_temperature": 20.9995, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T15:40:08.183224+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 62.2, + "water_total": 5477.0, + "average_temperature": 31.6667, + "experience_temperature": 20.9995, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T15:50:06.737441+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 63.8, + "water_total": 5581.0, + "average_temperature": 32.2333, + "experience_temperature": 21.8862, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T16:10:06.927464+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.7, + "humidity": 68.0, + "water_total": 5682.0, + "average_temperature": 31.7333, + "experience_temperature": 21.4976, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T16:20:07.724315+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 69.8, + "water_total": 5717.0, + "average_temperature": 31.6, + "experience_temperature": 22.0886, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T16:30:06.646733+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 69.8, + "water_total": 5717.0, + "average_temperature": 31.6, + "experience_temperature": 22.0886, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T16:40:07.211822+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.8, + "humidity": 69.7, + "water_total": 5774.0, + "average_temperature": 31.2667, + "experience_temperature": 21.0067, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T16:50:06.394373+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 70.0, + "water_total": 5815.0, + "average_temperature": 31.4, + "experience_temperature": 22.2929, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T17:10:07.921985+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 70.2, + "water_total": 45.0, + "average_temperature": 31.1333, + "experience_temperature": 22.0662, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T17:20:06.134989+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.3, + "humidity": 69.8, + "water_total": 104.0, + "average_temperature": 30.8667, + "experience_temperature": 22.4481, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T17:30:06.402622+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.4, + "humidity": 70.9, + "water_total": 147.0, + "average_temperature": 30.7, + "experience_temperature": 22.1371, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T17:40:06.114447+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 71.2, + "water_total": 187.0, + "average_temperature": 30.5667, + "experience_temperature": 23.1567, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T17:50:08.275279+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.6, + "humidity": 72.4, + "water_total": 222.0, + "average_temperature": 30.3, + "experience_temperature": 21.3086, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:00:07.046246+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.3, + "humidity": 73.1, + "water_total": 227.0, + "average_temperature": 30.1333, + "experience_temperature": 22.3748, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:10:05.840205+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 73.3, + "water_total": 227.0, + "average_temperature": 30.0, + "experience_temperature": 23.3743, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:20:06.428403+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.2, + "humidity": 73.8, + "water_total": 227.0, + "average_temperature": 29.9, + "experience_temperature": 22.6457, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:30:07.748824+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 71.9, + "water_total": 227.0, + "average_temperature": 30.0, + "experience_temperature": 23.0943, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:40:07.224505+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 72.6, + "water_total": 227.0, + "average_temperature": 30.4667, + "experience_temperature": 21.8795, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T18:50:05.668233+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.5, + "humidity": 74.2, + "water_total": 324.0, + "average_temperature": 30.0667, + "experience_temperature": 21.7995, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:00:08.967759+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.3, + "humidity": 74.4, + "water_total": 402.0, + "average_temperature": 30.0333, + "experience_temperature": 22.5348, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:10:06.807424+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.4, + "humidity": 72.9, + "water_total": 466.0, + "average_temperature": 30.1333, + "experience_temperature": 21.9705, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:20:07.063877+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.3, + "humidity": 71.7, + "water_total": 512.0, + "average_temperature": 30.2, + "experience_temperature": 22.1614, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:30:08.766056+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 74.1, + "water_total": 572.0, + "average_temperature": 29.8667, + "experience_temperature": 23.0367, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:40:07.511177+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.2, + "humidity": 72.7, + "water_total": 631.0, + "average_temperature": 29.9667, + "experience_temperature": 22.4924, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T19:50:08.135454+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 73.3, + "water_total": 692.0, + "average_temperature": 29.8667, + "experience_temperature": 23.241, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:00:09.545653+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 74.6, + "water_total": 741.0, + "average_temperature": 29.6, + "experience_temperature": 23.5986, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:10:06.183353+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 73.9, + "water_total": 799.0, + "average_temperature": 29.6333, + "experience_temperature": 23.8562, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:20:06.586687+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 73.6, + "water_total": 840.0, + "average_temperature": 29.7, + "experience_temperature": 23.1343, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:30:06.531314+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 73.8, + "water_total": 884.0, + "average_temperature": 29.4, + "experience_temperature": 23.2386, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:40:07.167831+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.2, + "humidity": 74.8, + "water_total": 925.0, + "average_temperature": 29.5, + "experience_temperature": 22.4457, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T20:50:07.662964+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 75.3, + "water_total": 959.0, + "average_temperature": 29.4, + "experience_temperature": 23.5386, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:00:07.730043+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 76.6, + "water_total": 1007.0, + "average_temperature": 29.4, + "experience_temperature": 23.07, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:10:08.176661+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.0, + "humidity": 77.1, + "water_total": 1023.0, + "average_temperature": 29.3333, + "experience_temperature": 23.4676, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:20:07.277178+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 77.7, + "water_total": 1060.0, + "average_temperature": 29.0333, + "experience_temperature": 22.9233, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:30:07.703704+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 2.1, + "humidity": 77.7, + "water_total": 1060.0, + "average_temperature": 29.0333, + "experience_temperature": 22.9233, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:40:06.478368+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 79.0, + "water_total": 1171.0, + "average_temperature": 29.0333, + "experience_temperature": 24.2762, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T21:50:09.685929+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 79.6, + "water_total": 1217.0, + "average_temperature": 28.7, + "experience_temperature": 24.4271, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:00:07.784273+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.6, + "humidity": 78.8, + "water_total": 1262.0, + "average_temperature": 28.7333, + "experience_temperature": 24.6648, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:10:06.591969+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 78.2, + "water_total": 1315.0, + "average_temperature": 28.7667, + "experience_temperature": 24.2138, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:20:06.530511+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 79.4, + "water_total": 1387.0, + "average_temperature": 28.3667, + "experience_temperature": 23.6895, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:30:06.105369+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 80.8, + "water_total": 1445.0, + "average_temperature": 28.0, + "experience_temperature": 23.6029, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:40:06.476669+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 81.6, + "water_total": 1479.0, + "average_temperature": 27.9667, + "experience_temperature": 23.3652, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T22:50:08.699073+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 81.0, + "water_total": 1521.0, + "average_temperature": 27.8333, + "experience_temperature": 23.8405, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:00:06.586081+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.8, + "humidity": 82.1, + "water_total": 1576.0, + "average_temperature": 27.7667, + "experience_temperature": 23.6295, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:10:07.554124+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 80.8, + "water_total": 1617.0, + "average_temperature": 27.7667, + "experience_temperature": 23.7338, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:20:08.136256+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.9, + "humidity": 81.7, + "water_total": 1650.0, + "average_temperature": 27.8333, + "experience_temperature": 23.2519, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:30:06.562995+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 81.8, + "water_total": 1666.0, + "average_temperature": 27.5, + "experience_temperature": 23.6671, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:40:06.502610+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.7, + "humidity": 81.5, + "water_total": 1666.0, + "average_temperature": 27.5667, + "experience_temperature": 23.6738, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-17T23:50:06.671755+07:00", + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.6, + "humidity": 81.3, + "water_total": 1666.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9981, + "chill_factor": 3.6429 + }, + { + "timestamp": "2026-06-18T00:00:06.560261+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 81.3, + "water_total": 1666.0, + "average_temperature": 27.5667, + "experience_temperature": 24.2267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T00:10:05.686759+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 81.8, + "water_total": 1666.0, + "average_temperature": 27.9667, + "experience_temperature": 24.3767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T00:20:06.200875+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 81.4, + "water_total": 1759.0, + "average_temperature": 27.9667, + "experience_temperature": 23.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T00:30:05.502979+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 83.1, + "water_total": 1822.0, + "average_temperature": 27.6667, + "experience_temperature": 24.6867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T00:40:06.572224+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 82.6, + "water_total": 1858.0, + "average_temperature": 27.5, + "experience_temperature": 23.37, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T00:50:06.499718+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 83.4, + "water_total": 1901.0, + "average_temperature": 27.6, + "experience_temperature": 23.98, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:00:07.089261+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 84.4, + "water_total": 1952.0, + "average_temperature": 27.6667, + "experience_temperature": 23.8967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:10:06.168313+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 83.0, + "water_total": 2004.0, + "average_temperature": 27.7667, + "experience_temperature": 23.7167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:20:06.616575+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 84.2, + "water_total": 2058.0, + "average_temperature": 27.5667, + "experience_temperature": 24.4567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:30:06.319498+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 83.3, + "water_total": 2102.0, + "average_temperature": 27.6333, + "experience_temperature": 25.0433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:40:06.310512+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 82.6, + "water_total": 2139.0, + "average_temperature": 27.5333, + "experience_temperature": 24.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T01:50:05.657748+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 82.6, + "water_total": 2178.0, + "average_temperature": 27.6667, + "experience_temperature": 23.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:00:05.741221+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 83.1, + "water_total": 2221.0, + "average_temperature": 27.6667, + "experience_temperature": 23.9867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:10:06.125261+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 83.0, + "water_total": 2262.0, + "average_temperature": 27.5667, + "experience_temperature": 24.9167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:20:06.145102+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 81.9, + "water_total": 2296.0, + "average_temperature": 27.7333, + "experience_temperature": 23.4633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:30:05.856275+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 82.6, + "water_total": 2330.0, + "average_temperature": 27.7, + "experience_temperature": 23.92, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:40:07.449368+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 83.1, + "water_total": 2370.0, + "average_temperature": 27.6667, + "experience_temperature": 23.6367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T02:50:06.162985+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 83.1, + "water_total": 2370.0, + "average_temperature": 27.6667, + "experience_temperature": 23.6367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:00:05.884457+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 82.2, + "water_total": 2404.0, + "average_temperature": 27.7333, + "experience_temperature": 23.5233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:10:06.182230+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 81.6, + "water_total": 2480.0, + "average_temperature": 27.6667, + "experience_temperature": 23.3367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:20:06.799656+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 82.8, + "water_total": 2514.0, + "average_temperature": 27.6, + "experience_temperature": 23.86, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:30:09.452495+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 83.0, + "water_total": 2554.0, + "average_temperature": 27.5333, + "experience_temperature": 23.8333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:40:06.474013+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 82.9, + "water_total": 2585.0, + "average_temperature": 27.5333, + "experience_temperature": 24.1633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T03:50:05.787715+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 82.3, + "water_total": 2618.0, + "average_temperature": 27.4333, + "experience_temperature": 23.5933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:00:06.424177+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 82.3, + "water_total": 2618.0, + "average_temperature": 27.4333, + "experience_temperature": 23.5933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:10:05.535653+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 83.6, + "water_total": 2677.0, + "average_temperature": 27.1, + "experience_temperature": 23.87, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:20:06.042757+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 84.5, + "water_total": 2710.0, + "average_temperature": 26.8333, + "experience_temperature": 25.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:30:07.321889+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 86.0, + "water_total": 2759.0, + "average_temperature": 27.0333, + "experience_temperature": 24.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:40:05.701678+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.2, + "water_total": 2804.0, + "average_temperature": 26.9, + "experience_temperature": 25.39, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T04:50:06.400809+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.4, + "water_total": 2844.0, + "average_temperature": 26.8, + "experience_temperature": 25.33, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:00:06.271444+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 86.4, + "water_total": 2884.0, + "average_temperature": 26.5333, + "experience_temperature": 24.9133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:10:07.175400+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 85.9, + "water_total": 2911.0, + "average_temperature": 26.6, + "experience_temperature": 24.88, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:20:06.362511+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 84.7, + "water_total": 2938.0, + "average_temperature": 26.1667, + "experience_temperature": 24.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:30:06.214160+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 86.5, + "water_total": 2946.0, + "average_temperature": 26.0667, + "experience_temperature": 25.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:40:05.814731+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.3, + "water_total": 2966.0, + "average_temperature": 25.9, + "experience_temperature": 24.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T05:50:05.385260+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.3, + "water_total": 2966.0, + "average_temperature": 25.9, + "experience_temperature": 24.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:00:05.763783+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.1, + "humidity": 85.1, + "water_total": 3071.0, + "average_temperature": 26.3667, + "experience_temperature": 25.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:10:05.763112+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.6, + "water_total": 3111.0, + "average_temperature": 25.9667, + "experience_temperature": 24.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:20:06.754224+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 85.8, + "water_total": 3158.0, + "average_temperature": 25.8, + "experience_temperature": 24.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:30:06.418083+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 86.3, + "water_total": 3207.0, + "average_temperature": 25.7667, + "experience_temperature": 24.4767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:40:06.202638+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 85.7, + "water_total": 3252.0, + "average_temperature": 25.7667, + "experience_temperature": 24.7067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T06:50:06.560019+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.1, + "humidity": 85.5, + "water_total": 3306.0, + "average_temperature": 25.9667, + "experience_temperature": 25.2167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:00:06.315405+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 86.2, + "water_total": 3359.0, + "average_temperature": 26.0667, + "experience_temperature": 25.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:10:05.746843+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 85.5, + "water_total": 3413.0, + "average_temperature": 26.1, + "experience_temperature": 25.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:20:06.630040+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 84.2, + "water_total": 3472.0, + "average_temperature": 26.3667, + "experience_temperature": 24.6567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:30:12.868990+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 83.3, + "water_total": 3536.0, + "average_temperature": 26.6, + "experience_temperature": 24.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:40:06.472236+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.2, + "humidity": 82.6, + "water_total": 3616.0, + "average_temperature": 26.8333, + "experience_temperature": 25.1533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T07:50:08.658430+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 80.2, + "water_total": 3670.0, + "average_temperature": 27.2333, + "experience_temperature": 24.0233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:00:06.945620+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 80.2, + "water_total": 3670.0, + "average_temperature": 27.2333, + "experience_temperature": 24.0233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:10:09.508357+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 79.1, + "water_total": 3741.0, + "average_temperature": 28.1333, + "experience_temperature": 25.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:20:07.197749+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 79.1, + "water_total": 3741.0, + "average_temperature": 28.1333, + "experience_temperature": 25.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:30:07.364465+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.2, + "humidity": 76.2, + "water_total": 3858.0, + "average_temperature": 28.8667, + "experience_temperature": 22.4067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:40:06.160099+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 76.0, + "water_total": 3907.0, + "average_temperature": 29.2667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T08:50:06.597199+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 76.0, + "water_total": 3907.0, + "average_temperature": 29.2667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:00:06.988984+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.0, + "humidity": 73.0, + "water_total": 4021.0, + "average_temperature": 29.7, + "experience_temperature": 23.3, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:10:07.178939+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.2, + "humidity": 70.7, + "water_total": 4079.0, + "average_temperature": 30.0, + "experience_temperature": 22.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:20:07.675161+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 4132.0, + "average_temperature": 30.1333, + "experience_temperature": 23.6833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:30:06.861049+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.3, + "humidity": 70.6, + "water_total": 4172.0, + "average_temperature": 30.6, + "experience_temperature": 22.67, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:40:08.886102+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 68.0, + "water_total": 4229.0, + "average_temperature": 31.0, + "experience_temperature": 21.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T09:50:10.460796+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 65.0, + "water_total": 4269.0, + "average_temperature": 31.1333, + "experience_temperature": 21.3833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T10:00:06.424315+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 63.7, + "water_total": 4321.0, + "average_temperature": 31.4667, + "experience_temperature": 21.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T10:10:06.432574+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.1, + "humidity": 62.5, + "water_total": 4381.0, + "average_temperature": 31.9333, + "experience_temperature": 19.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T10:30:09.299695+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 61.5, + "water_total": 4473.0, + "average_temperature": 32.1667, + "experience_temperature": 20.6667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T10:40:07.701188+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.0, + "humidity": 62.6, + "water_total": 4533.0, + "average_temperature": 32.3667, + "experience_temperature": 20.3867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T10:50:08.946964+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.2, + "humidity": 60.7, + "water_total": 4588.0, + "average_temperature": 32.1, + "experience_temperature": 19.04, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:00:10.105647+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.4, + "humidity": 60.1, + "water_total": 4665.0, + "average_temperature": 32.2, + "experience_temperature": 21.82, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:10:06.774807+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.7, + "humidity": 59.7, + "water_total": 4739.0, + "average_temperature": 32.1333, + "experience_temperature": 20.6233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:20:07.686845+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 60.1, + "water_total": 4794.0, + "average_temperature": 32.3333, + "experience_temperature": 21.2533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:30:07.120091+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 61.1, + "water_total": 4889.0, + "average_temperature": 32.1333, + "experience_temperature": 20.2033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:40:06.486795+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 59.6, + "water_total": 4959.0, + "average_temperature": 32.3333, + "experience_temperature": 20.4533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T11:50:09.807743+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.1, + "humidity": 60.9, + "water_total": 5006.0, + "average_temperature": 32.0, + "experience_temperature": 22.83, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:00:07.372473+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.1, + "humidity": 61.0, + "water_total": 5080.0, + "average_temperature": 32.7333, + "experience_temperature": 20.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:10:06.674508+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 62.0, + "water_total": 5148.0, + "average_temperature": 32.1333, + "experience_temperature": 21.4333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:20:07.715470+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 61.9, + "water_total": 5202.0, + "average_temperature": 32.0667, + "experience_temperature": 20.6467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:30:06.626743+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.1, + "humidity": 63.2, + "water_total": 5263.0, + "average_temperature": 32.0333, + "experience_temperature": 19.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:40:06.770482+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 61.2, + "water_total": 5314.0, + "average_temperature": 32.3, + "experience_temperature": 21.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T12:50:07.746409+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.7, + "humidity": 61.7, + "water_total": 5387.0, + "average_temperature": 32.0333, + "experience_temperature": 20.9233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:00:08.247152+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.2, + "humidity": 61.2, + "water_total": 5431.0, + "average_temperature": 32.5667, + "experience_temperature": 19.6067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:10:09.751375+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.0, + "humidity": 61.6, + "water_total": 5501.0, + "average_temperature": 31.8667, + "experience_temperature": 19.6867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:20:06.256602+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 60.1, + "water_total": 5564.0, + "average_temperature": 32.4667, + "experience_temperature": 20.3367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:30:06.770691+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.0, + "humidity": 60.9, + "water_total": 5627.0, + "average_temperature": 32.1667, + "experience_temperature": 19.8467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:40:06.970017+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.7, + "humidity": 62.0, + "water_total": 5679.0, + "average_temperature": 32.0, + "experience_temperature": 20.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T13:50:06.883044+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 61.2, + "water_total": 5741.0, + "average_temperature": 32.5, + "experience_temperature": 20.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T14:10:07.190491+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 61.0, + "water_total": 5867.0, + "average_temperature": 32.1667, + "experience_temperature": 20.5667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T14:20:07.381678+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 61.3, + "water_total": 5925.0, + "average_temperature": 32.0333, + "experience_temperature": 20.4933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T14:30:06.304333+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 61.4, + "water_total": 5962.0, + "average_temperature": 31.7, + "experience_temperature": 21.23, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T14:40:06.703849+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 60.3, + "water_total": 6016.0, + "average_temperature": 32.3667, + "experience_temperature": 20.2767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T14:50:06.732790+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 60.3, + "water_total": 6062.0, + "average_temperature": 32.6667, + "experience_temperature": 20.5767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T15:10:08.458860+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.8, + "humidity": 62.2, + "water_total": 6176.0, + "average_temperature": 32.3667, + "experience_temperature": 21.0067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T15:20:06.237767+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 3.0, + "humidity": 63.4, + "water_total": 6251.0, + "average_temperature": 32.0667, + "experience_temperature": 20.2467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T15:30:09.355785+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 67.8, + "water_total": 6301.0, + "average_temperature": 31.9667, + "experience_temperature": 22.4267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T15:40:06.746955+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 67.5, + "water_total": 6355.0, + "average_temperature": 32.0, + "experience_temperature": 21.35, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T15:50:09.132210+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.7, + "humidity": 67.1, + "water_total": 6423.0, + "average_temperature": 32.0667, + "experience_temperature": 22.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T16:10:06.660590+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 67.5, + "water_total": 6531.0, + "average_temperature": 31.8, + "experience_temperature": 22.55, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T16:20:07.073794+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.9, + "humidity": 67.9, + "water_total": 6567.0, + "average_temperature": 31.7667, + "experience_temperature": 21.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T16:30:07.034159+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 68.6, + "water_total": 6634.0, + "average_temperature": 31.4333, + "experience_temperature": 22.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T16:40:07.361410+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 68.6, + "water_total": 6634.0, + "average_temperature": 31.4333, + "experience_temperature": 22.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T16:50:06.957997+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 70.3, + "water_total": 6759.0, + "average_temperature": 31.1333, + "experience_temperature": 22.0933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T17:10:07.105057+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 69.6, + "water_total": 6860.0, + "average_temperature": 30.9667, + "experience_temperature": 22.1367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T17:20:06.866709+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.4, + "humidity": 69.8, + "water_total": 6898.0, + "average_temperature": 30.8, + "experience_temperature": 22.36, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T17:30:06.505053+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.2, + "humidity": 69.8, + "water_total": 6951.0, + "average_temperature": 30.6, + "experience_temperature": 22.86, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T17:40:07.440280+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 71.9, + "water_total": 6998.0, + "average_temperature": 30.2333, + "experience_temperature": 21.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T17:50:06.464498+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 72.0, + "water_total": 7014.0, + "average_temperature": 29.8667, + "experience_temperature": 21.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:00:08.703608+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 72.4, + "water_total": 7019.0, + "average_temperature": 29.7, + "experience_temperature": 21.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:10:06.570941+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.5, + "humidity": 72.4, + "water_total": 7019.0, + "average_temperature": 29.7, + "experience_temperature": 21.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:20:06.072117+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 73.1, + "water_total": 7019.0, + "average_temperature": 29.6, + "experience_temperature": 24.62, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:30:07.775674+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.1, + "humidity": 72.9, + "water_total": 7023.0, + "average_temperature": 29.5667, + "experience_temperature": 22.7967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:40:05.658120+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.6, + "humidity": 73.0, + "water_total": 7023.0, + "average_temperature": 29.6667, + "experience_temperature": 21.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T18:50:05.988417+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 74.0, + "water_total": 7111.0, + "average_temperature": 29.5333, + "experience_temperature": 23.6833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:00:06.455691+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.2, + "humidity": 74.7, + "water_total": 7191.0, + "average_temperature": 29.3333, + "experience_temperature": 22.5733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:10:05.335395+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.2, + "humidity": 74.7, + "water_total": 7191.0, + "average_temperature": 29.3333, + "experience_temperature": 22.5733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:20:05.736249+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.0, + "humidity": 76.2, + "water_total": 7301.0, + "average_temperature": 29.0333, + "experience_temperature": 23.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:30:06.338841+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 2.1, + "humidity": 77.2, + "water_total": 7349.0, + "average_temperature": 29.0333, + "experience_temperature": 23.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:40:06.627283+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 78.6, + "water_total": 7414.0, + "average_temperature": 28.7667, + "experience_temperature": 23.8367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T19:50:05.195307+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 79.1, + "water_total": 7466.0, + "average_temperature": 28.5333, + "experience_temperature": 25.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:00:06.667563+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 78.9, + "water_total": 7523.0, + "average_temperature": 28.5667, + "experience_temperature": 24.3967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:10:05.641744+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 78.8, + "water_total": 7568.0, + "average_temperature": 28.4667, + "experience_temperature": 23.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:20:05.995863+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 79.9, + "water_total": 7613.0, + "average_temperature": 28.3, + "experience_temperature": 23.98, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:30:09.478432+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 80.1, + "water_total": 7654.0, + "average_temperature": 28.4333, + "experience_temperature": 24.8533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:40:05.994864+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 79.9, + "water_total": 7697.0, + "average_temperature": 28.3667, + "experience_temperature": 24.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T20:50:05.956643+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 79.6, + "water_total": 7740.0, + "average_temperature": 28.3, + "experience_temperature": 23.92, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:00:08.197691+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 80.4, + "water_total": 7783.0, + "average_temperature": 28.0667, + "experience_temperature": 23.4967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:10:08.004646+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 81.1, + "water_total": 7816.0, + "average_temperature": 28.0333, + "experience_temperature": 23.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:20:05.843892+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.5, + "humidity": 81.5, + "water_total": 7853.0, + "average_temperature": 27.9667, + "experience_temperature": 25.0167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:30:06.655193+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 81.6, + "water_total": 7911.0, + "average_temperature": 27.7, + "experience_temperature": 24.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:40:05.385763+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 81.8, + "water_total": 7951.0, + "average_temperature": 27.5, + "experience_temperature": 23.91, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T21:50:06.238098+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 82.7, + "water_total": 7975.0, + "average_temperature": 27.4, + "experience_temperature": 23.99, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:00:05.970472+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 83.5, + "water_total": 8001.0, + "average_temperature": 27.1, + "experience_temperature": 23.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:10:06.260152+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 83.5, + "water_total": 8022.0, + "average_temperature": 27.1333, + "experience_temperature": 23.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:20:06.289382+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 83.4, + "water_total": 8048.0, + "average_temperature": 26.9, + "experience_temperature": 23.28, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:30:05.847181+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 84.0, + "water_total": 8074.0, + "average_temperature": 26.9667, + "experience_temperature": 24.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:40:06.139524+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.9, + "humidity": 82.6, + "water_total": 8131.0, + "average_temperature": 27.6, + "experience_temperature": 23.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T22:50:06.118761+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 82.6, + "water_total": 8164.0, + "average_temperature": 27.1333, + "experience_temperature": 24.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:00:05.615380+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 82.6, + "water_total": 8164.0, + "average_temperature": 27.1333, + "experience_temperature": 24.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:10:06.108723+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.7, + "humidity": 84.5, + "water_total": 8245.0, + "average_temperature": 27.0, + "experience_temperature": 23.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:20:05.734276+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.3, + "humidity": 83.7, + "water_total": 8270.0, + "average_temperature": 26.6333, + "experience_temperature": 24.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:30:06.587611+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 8270.0, + "average_temperature": 26.6667, + "experience_temperature": 23.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:40:06.240287+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.8, + "humidity": 84.5, + "water_total": 8274.0, + "average_temperature": 26.6333, + "experience_temperature": 23.2333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-18T23:50:06.168864+07:00", + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 84.4, + "water_total": 8274.0, + "average_temperature": 26.5667, + "experience_temperature": 24.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:00:06.025008+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 85.2, + "water_total": 8274.0, + "average_temperature": 26.5667, + "experience_temperature": 23.3067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:10:05.720151+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 84.8, + "water_total": 8274.0, + "average_temperature": 26.7333, + "experience_temperature": 23.7433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:20:07.292545+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 84.9, + "water_total": 8372.0, + "average_temperature": 26.7, + "experience_temperature": 23.73, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:30:06.018144+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 84.9, + "water_total": 8372.0, + "average_temperature": 26.7, + "experience_temperature": 23.73, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:40:06.149476+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 85.2, + "water_total": 8514.0, + "average_temperature": 26.6667, + "experience_temperature": 23.4067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T00:50:05.688243+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.5, + "humidity": 84.9, + "water_total": 8555.0, + "average_temperature": 26.4667, + "experience_temperature": 24.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:00:07.213054+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.1, + "humidity": 85.4, + "water_total": 8591.0, + "average_temperature": 26.4667, + "experience_temperature": 25.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:10:06.230632+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 84.7, + "water_total": 8661.0, + "average_temperature": 26.4667, + "experience_temperature": 24.8567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:20:06.106441+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 85.5, + "water_total": 8728.0, + "average_temperature": 26.2333, + "experience_temperature": 24.7833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:30:06.399896+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 8769.0, + "average_temperature": 26.1667, + "experience_temperature": 25.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:40:06.225242+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 85.8, + "water_total": 8836.0, + "average_temperature": 26.1, + "experience_temperature": 25.06, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T01:50:07.025292+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 85.7, + "water_total": 8889.0, + "average_temperature": 26.0, + "experience_temperature": 24.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:00:06.117815+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 85.7, + "water_total": 8889.0, + "average_temperature": 26.0, + "experience_temperature": 24.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:10:05.883133+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 85.8, + "water_total": 9001.0, + "average_temperature": 25.7333, + "experience_temperature": 24.3433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:20:06.205328+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.7, + "water_total": 9041.0, + "average_temperature": 25.6333, + "experience_temperature": 24.4233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:30:06.404328+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 87.7, + "water_total": 9075.0, + "average_temperature": 25.8333, + "experience_temperature": 25.1733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:40:06.958984+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.0, + "water_total": 9115.0, + "average_temperature": 25.6333, + "experience_temperature": 24.6333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T02:50:06.191887+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.5, + "water_total": 9154.0, + "average_temperature": 25.6, + "experience_temperature": 24.7, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:00:06.053451+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.3, + "water_total": 9188.0, + "average_temperature": 25.5, + "experience_temperature": 24.21, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:10:06.228465+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 9222.0, + "average_temperature": 25.5667, + "experience_temperature": 24.4167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:20:06.372362+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 9257.0, + "average_temperature": 25.4667, + "experience_temperature": 24.4867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:30:06.751918+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.3, + "water_total": 9291.0, + "average_temperature": 25.3333, + "experience_temperature": 24.3933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:40:07.177274+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.7, + "water_total": 9325.0, + "average_temperature": 25.3, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T03:50:05.892877+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 9362.0, + "average_temperature": 25.1667, + "experience_temperature": 24.3067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:00:07.170516+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.3, + "water_total": 9397.0, + "average_temperature": 25.1333, + "experience_temperature": 23.8433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:10:06.277060+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.4, + "humidity": 87.7, + "water_total": 9444.0, + "average_temperature": 25.3667, + "experience_temperature": 24.0067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:20:06.413456+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.7, + "water_total": 9477.0, + "average_temperature": 25.2, + "experience_temperature": 24.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:30:06.655624+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 87.2, + "water_total": 9520.0, + "average_temperature": 25.1, + "experience_temperature": 24.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:40:06.550600+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.5, + "water_total": 9538.0, + "average_temperature": 24.8, + "experience_temperature": 23.75, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T04:50:07.464760+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.1, + "humidity": 87.5, + "water_total": 9538.0, + "average_temperature": 24.6333, + "experience_temperature": 24.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:00:06.856074+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.5, + "water_total": 9538.0, + "average_temperature": 24.7, + "experience_temperature": 23.65, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:10:05.991732+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 85.8, + "water_total": 9591.0, + "average_temperature": 24.9333, + "experience_temperature": 23.8933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:20:06.042729+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.1, + "water_total": 9629.0, + "average_temperature": 24.7333, + "experience_temperature": 23.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:30:06.525434+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.1, + "water_total": 9644.0, + "average_temperature": 24.5333, + "experience_temperature": 23.2033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:40:07.518050+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.4, + "water_total": 9658.0, + "average_temperature": 24.5333, + "experience_temperature": 23.6133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T05:50:08.241471+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.4, + "humidity": 86.9, + "water_total": 9673.0, + "average_temperature": 24.5667, + "experience_temperature": 23.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:00:06.661282+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.6, + "water_total": 9694.0, + "average_temperature": 24.5, + "experience_temperature": 23.27, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:10:06.391274+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.8, + "water_total": 9715.0, + "average_temperature": 24.6, + "experience_temperature": 23.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:20:06.562666+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.4, + "humidity": 86.7, + "water_total": 9736.0, + "average_temperature": 24.5667, + "experience_temperature": 23.0067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:30:06.920774+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 9831.0, + "average_temperature": 24.6333, + "experience_temperature": 23.4833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:40:06.663042+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 86.9, + "water_total": 9897.0, + "average_temperature": 25.1, + "experience_temperature": 24.28, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T06:50:06.725895+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 86.8, + "water_total": 9941.0, + "average_temperature": 24.5667, + "experience_temperature": 23.3767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:00:06.983662+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 87.8, + "water_total": 9976.0, + "average_temperature": 24.6667, + "experience_temperature": 23.6767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:10:07.652375+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.1, + "humidity": 86.4, + "water_total": 10031.0, + "average_temperature": 25.0333, + "experience_temperature": 24.4633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:20:07.258048+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.1, + "humidity": 86.4, + "water_total": 10100.0, + "average_temperature": 25.4667, + "experience_temperature": 24.8967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:30:07.088133+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.2, + "humidity": 85.0, + "water_total": 10180.0, + "average_temperature": 25.8333, + "experience_temperature": 24.6333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:40:06.558345+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.3, + "humidity": 84.1, + "water_total": 10255.0, + "average_temperature": 26.1667, + "experience_temperature": 24.4367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T07:50:06.849934+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 84.1, + "water_total": 10323.0, + "average_temperature": 26.5333, + "experience_temperature": 23.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:00:07.057545+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 84.1, + "water_total": 10323.0, + "average_temperature": 26.5333, + "experience_temperature": 23.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:10:06.466967+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 83.6, + "water_total": 10373.0, + "average_temperature": 26.9667, + "experience_temperature": 23.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:20:06.985062+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.4, + "humidity": 79.8, + "water_total": 10495.0, + "average_temperature": 27.8667, + "experience_temperature": 24.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:30:08.481430+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.5, + "humidity": 78.8, + "water_total": 10575.0, + "average_temperature": 28.3667, + "experience_temperature": 24.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:40:06.882358+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 76.9, + "water_total": 10655.0, + "average_temperature": 28.6, + "experience_temperature": 23.68, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T08:50:07.780671+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 75.2, + "water_total": 10719.0, + "average_temperature": 29.2667, + "experience_temperature": 23.6567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:00:06.872929+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 73.5, + "water_total": 10784.0, + "average_temperature": 29.5, + "experience_temperature": 23.55, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:10:08.732288+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.2, + "humidity": 73.1, + "water_total": 10845.0, + "average_temperature": 29.8333, + "experience_temperature": 22.7533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:20:08.283882+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 71.5, + "water_total": 10936.0, + "average_temperature": 30.2333, + "experience_temperature": 23.8833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:30:06.583295+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.0, + "humidity": 69.7, + "water_total": 10994.0, + "average_temperature": 30.6333, + "experience_temperature": 23.5733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:40:06.655461+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.4, + "humidity": 68.7, + "water_total": 11053.0, + "average_temperature": 30.8333, + "experience_temperature": 22.1733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T09:50:07.221218+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.4, + "humidity": 65.4, + "water_total": 11109.0, + "average_temperature": 31.1667, + "experience_temperature": 21.8467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:00:06.405071+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.8, + "humidity": 64.1, + "water_total": 11172.0, + "average_temperature": 31.6333, + "experience_temperature": 20.6533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:10:06.020961+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 62.7, + "water_total": 11245.0, + "average_temperature": 32.0, + "experience_temperature": 20.04, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:20:06.478521+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 60.3, + "water_total": 11294.0, + "average_temperature": 31.8667, + "experience_temperature": 19.4267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:30:07.520532+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.8, + "humidity": 61.0, + "water_total": 11356.0, + "average_temperature": 32.2, + "experience_temperature": 20.6, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:40:06.137976+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 59.7, + "water_total": 11432.0, + "average_temperature": 32.2, + "experience_temperature": 20.69, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T10:50:06.024672+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 57.3, + "water_total": 11500.0, + "average_temperature": 32.2333, + "experience_temperature": 20.9433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T11:00:06.926278+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 58.7, + "water_total": 11560.0, + "average_temperature": 32.3333, + "experience_temperature": 21.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T11:10:06.220965+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.1, + "humidity": 57.1, + "water_total": 11628.0, + "average_temperature": 32.7, + "experience_temperature": 19.27, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T11:20:06.615459+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 55.3, + "water_total": 11699.0, + "average_temperature": 32.4333, + "experience_temperature": 20.0433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T11:30:06.291354+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.2, + "humidity": 56.2, + "water_total": 11747.0, + "average_temperature": 32.6667, + "experience_temperature": 18.7067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T11:50:06.152843+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 55.6, + "water_total": 11855.0, + "average_temperature": 32.3333, + "experience_temperature": 20.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T12:20:06.064347+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.1, + "humidity": 55.6, + "water_total": 11975.0, + "average_temperature": 32.6333, + "experience_temperature": 18.9033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T12:30:06.053203+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 57.3, + "water_total": 12001.0, + "average_temperature": 32.9667, + "experience_temperature": 19.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T12:40:07.762762+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.3, + "humidity": 54.2, + "water_total": 12017.0, + "average_temperature": 32.5333, + "experience_temperature": 17.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T12:50:06.224839+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.2, + "humidity": 54.1, + "water_total": 12026.0, + "average_temperature": 32.7333, + "experience_temperature": 18.3533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:00:06.839575+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.2, + "humidity": 54.1, + "water_total": 12026.0, + "average_temperature": 32.7333, + "experience_temperature": 18.3533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:10:09.087272+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 55.1, + "water_total": 12046.0, + "average_temperature": 32.9333, + "experience_temperature": 20.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:20:08.006595+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.9, + "humidity": 53.4, + "water_total": 12051.0, + "average_temperature": 32.8667, + "experience_temperature": 19.3967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:30:08.276068+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 53.7, + "water_total": 12056.0, + "average_temperature": 33.1333, + "experience_temperature": 20.4233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:40:05.835448+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.9, + "humidity": 54.7, + "water_total": 12065.0, + "average_temperature": 33.2333, + "experience_temperature": 20.0233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T13:50:06.901930+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.1, + "humidity": 54.3, + "water_total": 12065.0, + "average_temperature": 32.9333, + "experience_temperature": 18.9433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T14:10:06.145854+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.0, + "humidity": 73.6, + "water_total": 12065.0, + "average_temperature": 29.5, + "experience_temperature": 23.22, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T14:20:07.227029+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.2, + "humidity": 53.8, + "water_total": 12085.0, + "average_temperature": 33.2667, + "experience_temperature": 18.8267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T14:30:06.328453+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 54.7, + "water_total": 12137.0, + "average_temperature": 32.8, + "experience_temperature": 20.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T14:40:06.380340+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 63.0, + "water_total": 12258.0, + "average_temperature": 32.7667, + "experience_temperature": 22.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T14:50:06.762219+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 65.1, + "water_total": 12383.0, + "average_temperature": 32.1, + "experience_temperature": 20.62, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T15:10:07.447488+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.9, + "humidity": 68.5, + "water_total": 12576.0, + "average_temperature": 32.0, + "experience_temperature": 21.55, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T15:20:06.547884+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.9, + "humidity": 68.2, + "water_total": 12669.0, + "average_temperature": 32.2333, + "experience_temperature": 21.7233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T15:30:08.108984+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 66.9, + "water_total": 12738.0, + "average_temperature": 32.0667, + "experience_temperature": 20.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T15:40:08.052870+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.1, + "humidity": 67.6, + "water_total": 12808.0, + "average_temperature": 31.8, + "experience_temperature": 20.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T15:50:06.338733+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 68.5, + "water_total": 12901.0, + "average_temperature": 31.2, + "experience_temperature": 22.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T16:10:06.071794+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.0, + "humidity": 68.2, + "water_total": 13070.0, + "average_temperature": 31.7333, + "experience_temperature": 20.8733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T16:20:06.414596+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 3.1, + "humidity": 68.3, + "water_total": 13145.0, + "average_temperature": 31.6667, + "experience_temperature": 20.4767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T16:30:05.743922+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.8, + "humidity": 68.6, + "water_total": 13219.0, + "average_temperature": 31.6333, + "experience_temperature": 21.5533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T16:40:06.254710+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.6, + "humidity": 68.3, + "water_total": 13285.0, + "average_temperature": 31.4667, + "experience_temperature": 22.0267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T16:50:06.503475+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.0, + "humidity": 73.6, + "water_total": 13285.0, + "average_temperature": 29.5, + "experience_temperature": 23.22, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T17:10:05.994298+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.6, + "humidity": 69.1, + "water_total": 78.0, + "average_temperature": 30.9, + "experience_temperature": 21.62, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T17:20:06.795257+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.7, + "humidity": 69.2, + "water_total": 141.0, + "average_temperature": 30.9333, + "experience_temperature": 21.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T17:30:05.700670+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.6, + "humidity": 69.9, + "water_total": 203.0, + "average_temperature": 30.6667, + "experience_temperature": 21.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T17:40:06.886786+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.1, + "humidity": 70.1, + "water_total": 262.0, + "average_temperature": 30.5, + "experience_temperature": 23.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T17:50:06.189726+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.0, + "humidity": 72.0, + "water_total": 320.0, + "average_temperature": 30.3333, + "experience_temperature": 23.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:00:06.342606+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.3, + "humidity": 72.3, + "water_total": 385.0, + "average_temperature": 30.1667, + "experience_temperature": 22.5767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:10:06.264009+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.4, + "humidity": 72.9, + "water_total": 441.0, + "average_temperature": 29.9667, + "experience_temperature": 22.1467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:20:07.291290+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.8, + "humidity": 74.2, + "water_total": 495.0, + "average_temperature": 29.5667, + "experience_temperature": 20.6067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:30:07.902406+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.3, + "humidity": 74.3, + "water_total": 547.0, + "average_temperature": 29.6333, + "experience_temperature": 22.4433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:40:06.243704+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.1, + "humidity": 74.3, + "water_total": 602.0, + "average_temperature": 29.5333, + "experience_temperature": 23.0433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T18:50:06.525634+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.3, + "humidity": 75.5, + "water_total": 658.0, + "average_temperature": 29.4667, + "experience_temperature": 22.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:00:06.470488+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 75.3, + "water_total": 705.0, + "average_temperature": 29.5667, + "experience_temperature": 23.9767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:10:06.550485+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 75.1, + "water_total": 753.0, + "average_temperature": 29.5, + "experience_temperature": 21.77, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:20:06.937184+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.5, + "humidity": 75.1, + "water_total": 753.0, + "average_temperature": 29.5, + "experience_temperature": 21.77, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:30:06.414076+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 79.6, + "water_total": 836.0, + "average_temperature": 29.2333, + "experience_temperature": 24.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:40:06.076364+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 80.1, + "water_total": 869.0, + "average_temperature": 29.1667, + "experience_temperature": 24.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T19:50:06.068800+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 81.1, + "water_total": 905.0, + "average_temperature": 29.0, + "experience_temperature": 25.62, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:00:06.502122+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.2, + "humidity": 80.7, + "water_total": 938.0, + "average_temperature": 28.7667, + "experience_temperature": 23.2067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:10:05.923463+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.0, + "humidity": 81.0, + "water_total": 968.0, + "average_temperature": 28.5333, + "experience_temperature": 23.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:20:06.819520+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.1, + "humidity": 81.6, + "water_total": 1021.0, + "average_temperature": 28.5, + "experience_temperature": 23.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:30:07.251021+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 2.2, + "humidity": 81.5, + "water_total": 1091.0, + "average_temperature": 28.3667, + "experience_temperature": 22.9667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:40:06.323481+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 82.0, + "water_total": 1148.0, + "average_temperature": 28.3333, + "experience_temperature": 24.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T20:50:05.632692+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 83.0, + "water_total": 1199.0, + "average_temperature": 28.1667, + "experience_temperature": 24.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:00:07.583341+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 83.8, + "water_total": 1251.0, + "average_temperature": 28.1667, + "experience_temperature": 24.6267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:10:05.862144+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 83.8, + "water_total": 1251.0, + "average_temperature": 28.1667, + "experience_temperature": 24.6267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:20:06.056996+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 84.1, + "water_total": 1355.0, + "average_temperature": 27.7, + "experience_temperature": 24.92, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:30:05.796666+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 84.3, + "water_total": 1400.0, + "average_temperature": 27.8, + "experience_temperature": 24.36, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:40:06.060972+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 84.5, + "water_total": 1451.0, + "average_temperature": 27.4667, + "experience_temperature": 24.7667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T21:50:05.967047+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.5, + "humidity": 85.3, + "water_total": 1493.0, + "average_temperature": 27.6, + "experience_temperature": 25.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:00:06.727818+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 83.2, + "water_total": 1538.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:10:06.830413+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 83.2, + "water_total": 1538.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:20:05.727126+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 83.7, + "water_total": 1646.0, + "average_temperature": 27.6333, + "experience_temperature": 24.7733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:30:06.768682+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 83.7, + "water_total": 1715.0, + "average_temperature": 27.5667, + "experience_temperature": 24.0067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:40:06.702373+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 82.4, + "water_total": 1784.0, + "average_temperature": 27.7667, + "experience_temperature": 23.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T22:50:06.388282+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 82.8, + "water_total": 1847.0, + "average_temperature": 27.6, + "experience_temperature": 24.56, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:00:05.906701+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.8, + "humidity": 84.3, + "water_total": 1902.0, + "average_temperature": 27.5333, + "experience_temperature": 24.0933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:10:07.398449+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 83.1, + "water_total": 1963.0, + "average_temperature": 27.5333, + "experience_temperature": 24.2033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:20:06.070945+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 84.6, + "water_total": 2026.0, + "average_temperature": 27.4, + "experience_temperature": 23.67, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:30:06.849503+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.7, + "humidity": 85.1, + "water_total": 2058.0, + "average_temperature": 26.9667, + "experience_temperature": 24.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:40:06.537045+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.9, + "humidity": 85.3, + "water_total": 2076.0, + "average_temperature": 26.8, + "experience_temperature": 23.21, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-19T23:50:06.686608+07:00", + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 85.3, + "water_total": 2091.0, + "average_temperature": 26.8333, + "experience_temperature": 24.2933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:00:06.779181+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 85.6, + "water_total": 2105.0, + "average_temperature": 26.9333, + "experience_temperature": 24.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:10:07.473454+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 85.6, + "water_total": 2122.0, + "average_temperature": 27.0667, + "experience_temperature": 23.8867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:20:06.011052+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 84.5, + "water_total": 2210.0, + "average_temperature": 27.2333, + "experience_temperature": 23.8333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:30:06.285892+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 85.2, + "water_total": 2281.0, + "average_temperature": 27.1667, + "experience_temperature": 24.6067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:40:05.986117+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 85.2, + "water_total": 2281.0, + "average_temperature": 27.1667, + "experience_temperature": 24.6067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T00:50:05.923858+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 85.5, + "water_total": 2373.0, + "average_temperature": 27.0333, + "experience_temperature": 23.4833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:00:06.094369+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 85.6, + "water_total": 2413.0, + "average_temperature": 26.9667, + "experience_temperature": 24.1367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:10:06.383872+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 85.3, + "water_total": 2463.0, + "average_temperature": 27.0333, + "experience_temperature": 24.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:20:05.476285+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 86.2, + "water_total": 2518.0, + "average_temperature": 26.9667, + "experience_temperature": 23.9067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:30:06.030322+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 84.6, + "water_total": 2609.0, + "average_temperature": 27.0333, + "experience_temperature": 24.3533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:40:06.035391+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 86.3, + "water_total": 2669.0, + "average_temperature": 26.6, + "experience_temperature": 23.91, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T01:50:06.104886+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 86.4, + "water_total": 2710.0, + "average_temperature": 26.5, + "experience_temperature": 23.48, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:00:05.769622+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 86.8, + "water_total": 2743.0, + "average_temperature": 26.3333, + "experience_temperature": 23.7433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:10:06.109867+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.4, + "water_total": 2776.0, + "average_temperature": 26.3333, + "experience_temperature": 23.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:20:06.445538+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 86.5, + "water_total": 2808.0, + "average_temperature": 26.3, + "experience_temperature": 22.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:30:05.753205+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.3, + "water_total": 2849.0, + "average_temperature": 26.3, + "experience_temperature": 23.81, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:40:06.172466+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 86.6, + "water_total": 2889.0, + "average_temperature": 26.3, + "experience_temperature": 23.32, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T02:50:05.509464+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.7, + "water_total": 2946.0, + "average_temperature": 26.7, + "experience_temperature": 24.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:00:06.717248+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 88.2, + "water_total": 3002.0, + "average_temperature": 26.2333, + "experience_temperature": 24.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:10:06.219846+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 86.9, + "water_total": 3047.0, + "average_temperature": 26.2667, + "experience_temperature": 24.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:20:06.454515+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 3092.0, + "average_temperature": 26.3667, + "experience_temperature": 23.9967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:30:06.224976+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 3092.0, + "average_temperature": 26.3667, + "experience_temperature": 23.9967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:40:06.529968+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.1, + "water_total": 3236.0, + "average_temperature": 25.9333, + "experience_temperature": 24.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T03:50:05.627737+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 87.2, + "water_total": 3277.0, + "average_temperature": 25.9333, + "experience_temperature": 25.1733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:00:05.852156+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.0, + "humidity": 87.1, + "water_total": 3316.0, + "average_temperature": 26.0, + "experience_temperature": 25.92, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:10:05.185632+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 87.2, + "water_total": 3347.0, + "average_temperature": 25.9, + "experience_temperature": 24.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:20:05.404730+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 86.8, + "water_total": 3362.0, + "average_temperature": 25.7667, + "experience_temperature": 24.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:30:05.811338+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.0, + "humidity": 87.1, + "water_total": 3376.0, + "average_temperature": 25.8, + "experience_temperature": 25.72, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:40:05.803736+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 3391.0, + "average_temperature": 25.8333, + "experience_temperature": 24.9733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T04:50:06.161865+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.4, + "water_total": 3405.0, + "average_temperature": 25.7, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:00:05.845370+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.4, + "humidity": 87.3, + "water_total": 3415.0, + "average_temperature": 25.6667, + "experience_temperature": 24.2267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:10:06.677254+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.7, + "water_total": 3430.0, + "average_temperature": 25.9333, + "experience_temperature": 24.7233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:20:05.952765+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 87.1, + "water_total": 3491.0, + "average_temperature": 25.9, + "experience_temperature": 25.12, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:30:06.012733+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 86.4, + "water_total": 3568.0, + "average_temperature": 25.8667, + "experience_temperature": 24.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:40:06.447356+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 87.9, + "water_total": 3613.0, + "average_temperature": 25.6333, + "experience_temperature": 24.6633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T05:50:05.751729+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.4, + "humidity": 87.9, + "water_total": 3661.0, + "average_temperature": 25.6667, + "experience_temperature": 24.3467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:00:06.899071+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 88.2, + "water_total": 3690.0, + "average_temperature": 25.6, + "experience_temperature": 25.04, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:10:06.296917+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 3722.0, + "average_temperature": 25.5, + "experience_temperature": 24.35, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:20:06.756531+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.4, + "humidity": 86.2, + "water_total": 3742.0, + "average_temperature": 25.5333, + "experience_temperature": 23.8733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:30:06.899120+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.4, + "water_total": 3761.0, + "average_temperature": 25.5333, + "experience_temperature": 24.2633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:40:06.476637+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 87.1, + "water_total": 3774.0, + "average_temperature": 25.6, + "experience_temperature": 24.82, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T06:50:07.940488+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.9, + "water_total": 3784.0, + "average_temperature": 25.7, + "experience_temperature": 24.53, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:00:06.535311+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.4, + "humidity": 86.0, + "water_total": 3793.0, + "average_temperature": 25.7, + "experience_temperature": 24.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:10:06.184416+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 86.2, + "water_total": 3802.0, + "average_temperature": 25.8, + "experience_temperature": 22.74, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:20:06.253280+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 86.4, + "water_total": 3812.0, + "average_temperature": 26.0, + "experience_temperature": 23.33, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:30:05.622708+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 85.5, + "water_total": 3821.0, + "average_temperature": 26.2667, + "experience_temperature": 23.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:40:07.002905+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 87.0, + "water_total": 3829.0, + "average_temperature": 26.8, + "experience_temperature": 26.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T07:50:06.496695+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.5, + "humidity": 82.7, + "water_total": 3851.0, + "average_temperature": 27.2, + "experience_temperature": 24.49, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:00:05.512997+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 83.2, + "water_total": 4002.0, + "average_temperature": 27.4, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:10:18.905977+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 83.2, + "water_total": 4002.0, + "average_temperature": 27.4, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:20:06.361945+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.2, + "humidity": 81.7, + "water_total": 4193.0, + "average_temperature": 28.0667, + "experience_temperature": 22.7067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:30:06.746070+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 80.4, + "water_total": 4257.0, + "average_temperature": 28.4667, + "experience_temperature": 23.8967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:40:06.431213+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 77.2, + "water_total": 4359.0, + "average_temperature": 29.1667, + "experience_temperature": 25.0067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T08:50:06.129655+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.0, + "humidity": 75.9, + "water_total": 4451.0, + "average_temperature": 29.3, + "experience_temperature": 23.48, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:00:06.573955+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 76.4, + "water_total": 4511.0, + "average_temperature": 29.6667, + "experience_temperature": 22.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:10:06.570589+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 4574.0, + "average_temperature": 30.1, + "experience_temperature": 23.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:20:06.531758+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 73.0, + "water_total": 4645.0, + "average_temperature": 30.3667, + "experience_temperature": 22.2167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:30:05.939273+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 72.3, + "water_total": 4732.0, + "average_temperature": 30.9, + "experience_temperature": 23.31, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:40:06.495588+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 71.7, + "water_total": 4815.0, + "average_temperature": 30.9, + "experience_temperature": 21.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T09:50:07.054967+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 71.5, + "water_total": 4909.0, + "average_temperature": 31.2667, + "experience_temperature": 23.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:00:07.143186+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.6, + "humidity": 69.4, + "water_total": 4995.0, + "average_temperature": 31.5, + "experience_temperature": 22.28, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:10:06.067984+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 69.0, + "water_total": 5065.0, + "average_temperature": 31.7, + "experience_temperature": 22.05, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:20:06.324660+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 69.7, + "water_total": 5131.0, + "average_temperature": 31.9333, + "experience_temperature": 23.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:30:06.438853+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 70.3, + "water_total": 5212.0, + "average_temperature": 32.0333, + "experience_temperature": 21.9433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:40:06.727702+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.8, + "humidity": 67.7, + "water_total": 5294.0, + "average_temperature": 32.5333, + "experience_temperature": 22.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T10:50:06.302350+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 68.1, + "water_total": 5363.0, + "average_temperature": 31.8333, + "experience_temperature": 22.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:00:06.256313+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 67.6, + "water_total": 5439.0, + "average_temperature": 32.1, + "experience_temperature": 22.87, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:10:06.890008+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.8, + "humidity": 65.8, + "water_total": 5508.0, + "average_temperature": 32.3667, + "experience_temperature": 21.7267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:20:07.055266+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.1, + "humidity": 67.8, + "water_total": 5574.0, + "average_temperature": 32.3, + "experience_temperature": 21.01, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:30:06.883649+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 67.4, + "water_total": 5640.0, + "average_temperature": 32.1333, + "experience_temperature": 23.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:40:05.733579+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 65.3, + "water_total": 5683.0, + "average_temperature": 31.8, + "experience_temperature": 20.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T11:50:08.695866+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 64.7, + "water_total": 5775.0, + "average_temperature": 32.4667, + "experience_temperature": 21.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:00:05.898206+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 64.7, + "water_total": 5775.0, + "average_temperature": 32.4667, + "experience_temperature": 21.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:10:06.961319+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.3, + "humidity": 65.6, + "water_total": 5896.0, + "average_temperature": 32.4667, + "experience_temperature": 20.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:20:06.242279+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 64.5, + "water_total": 5946.0, + "average_temperature": 32.3667, + "experience_temperature": 21.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:30:07.164709+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.6, + "humidity": 63.4, + "water_total": 6004.0, + "average_temperature": 32.5333, + "experience_temperature": 22.1133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:40:05.762791+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.4, + "humidity": 62.9, + "water_total": 6067.0, + "average_temperature": 32.4333, + "experience_temperature": 22.6133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T12:50:07.535485+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.0, + "humidity": 64.4, + "water_total": 6121.0, + "average_temperature": 32.1667, + "experience_temperature": 20.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:00:06.464705+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 64.8, + "water_total": 6177.0, + "average_temperature": 32.5333, + "experience_temperature": 22.0433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:10:06.376367+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 64.8, + "water_total": 6230.0, + "average_temperature": 32.4333, + "experience_temperature": 21.2433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:20:06.212497+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 64.9, + "water_total": 6281.0, + "average_temperature": 32.3333, + "experience_temperature": 21.1633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:30:06.538880+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 64.9, + "water_total": 6281.0, + "average_temperature": 32.3333, + "experience_temperature": 21.1633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:40:07.207197+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.0, + "humidity": 64.7, + "water_total": 6394.0, + "average_temperature": 32.9, + "experience_temperature": 21.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T13:50:06.006013+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 64.8, + "water_total": 6451.0, + "average_temperature": 32.7667, + "experience_temperature": 22.9767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T14:10:06.834983+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 64.3, + "water_total": 6569.0, + "average_temperature": 32.5333, + "experience_temperature": 22.6433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T14:20:06.788800+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 64.3, + "water_total": 6622.0, + "average_temperature": 32.4333, + "experience_temperature": 21.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T14:30:06.564610+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 64.3, + "water_total": 6622.0, + "average_temperature": 32.4333, + "experience_temperature": 21.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T14:40:07.455715+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.1, + "humidity": 71.7, + "water_total": 6719.0, + "average_temperature": 32.2667, + "experience_temperature": 21.7567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T14:50:06.441530+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 72.2, + "water_total": 6775.0, + "average_temperature": 32.2667, + "experience_temperature": 22.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T15:10:06.376052+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 3.2, + "humidity": 76.3, + "water_total": 6870.0, + "average_temperature": 31.4, + "experience_temperature": 21.46, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T15:20:05.995792+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 75.4, + "water_total": 6916.0, + "average_temperature": 31.1, + "experience_temperature": 23.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T15:30:06.509116+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 72.7, + "water_total": 6948.0, + "average_temperature": 30.8667, + "experience_temperature": 21.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T15:40:11.510499+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.6, + "humidity": 72.4, + "water_total": 7009.0, + "average_temperature": 31.0333, + "experience_temperature": 22.4133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T15:50:06.742256+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.9, + "humidity": 73.0, + "water_total": 7070.0, + "average_temperature": 30.8333, + "experience_temperature": 21.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T16:10:07.447153+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 73.4, + "water_total": 7227.0, + "average_temperature": 30.9667, + "experience_temperature": 22.8967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T16:20:05.934475+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 73.9, + "water_total": 7293.0, + "average_temperature": 30.6667, + "experience_temperature": 22.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T16:30:08.143286+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.8, + "humidity": 74.9, + "water_total": 7365.0, + "average_temperature": 30.5333, + "experience_temperature": 21.7133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T16:40:06.824219+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 74.6, + "water_total": 7430.0, + "average_temperature": 30.5667, + "experience_temperature": 22.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T16:50:06.993785+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.8, + "humidity": 76.4, + "water_total": 7499.0, + "average_temperature": 30.5333, + "experience_temperature": 22.0133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T17:10:06.927910+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.7, + "humidity": 75.8, + "water_total": 64.0, + "average_temperature": 30.3, + "experience_temperature": 22.01, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T17:20:06.856317+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 76.5, + "water_total": 108.0, + "average_temperature": 30.3, + "experience_temperature": 22.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T17:30:06.243220+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 76.5, + "water_total": 161.0, + "average_temperature": 30.2, + "experience_temperature": 23.45, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T17:40:06.754165+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.2, + "humidity": 75.6, + "water_total": 211.0, + "average_temperature": 30.0667, + "experience_temperature": 23.4867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T17:50:06.413387+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 75.5, + "water_total": 272.0, + "average_temperature": 29.7333, + "experience_temperature": 22.7833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:00:06.661979+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.2, + "humidity": 78.1, + "water_total": 293.0, + "average_temperature": 29.5, + "experience_temperature": 23.42, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:10:07.180584+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.6, + "humidity": 78.9, + "water_total": 314.0, + "average_temperature": 29.2667, + "experience_temperature": 21.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:20:06.199191+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.6, + "humidity": 78.9, + "water_total": 314.0, + "average_temperature": 29.2667, + "experience_temperature": 21.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:30:06.492043+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 79.1, + "water_total": 362.0, + "average_temperature": 29.1667, + "experience_temperature": 22.2367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:40:06.392393+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 78.2, + "water_total": 384.0, + "average_temperature": 29.4333, + "experience_temperature": 22.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T18:50:06.263749+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.4, + "humidity": 76.9, + "water_total": 476.0, + "average_temperature": 29.5667, + "experience_temperature": 22.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:00:06.661851+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.2, + "humidity": 76.9, + "water_total": 570.0, + "average_temperature": 29.1667, + "experience_temperature": 22.8467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:10:06.487139+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.3, + "humidity": 76.8, + "water_total": 640.0, + "average_temperature": 29.3, + "experience_temperature": 22.61, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:20:06.135821+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.4, + "humidity": 76.1, + "water_total": 700.0, + "average_temperature": 29.3667, + "experience_temperature": 22.1867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:30:06.069468+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.5, + "humidity": 75.2, + "water_total": 766.0, + "average_temperature": 29.2333, + "experience_temperature": 21.5233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:40:05.885447+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 80.5, + "water_total": 810.0, + "average_temperature": 28.1667, + "experience_temperature": 23.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T19:50:07.298260+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.1, + "humidity": 82.0, + "water_total": 887.0, + "average_temperature": 27.9333, + "experience_temperature": 22.9833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:00:06.794703+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 2.0, + "humidity": 85.0, + "water_total": 942.0, + "average_temperature": 27.8, + "experience_temperature": 23.8, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:10:06.105803+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 84.7, + "water_total": 1039.0, + "average_temperature": 27.7667, + "experience_temperature": 24.0567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:20:05.901676+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.6, + "humidity": 85.4, + "water_total": 1093.0, + "average_temperature": 26.8667, + "experience_temperature": 24.3467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:30:06.282144+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 86.8, + "water_total": 1149.0, + "average_temperature": 26.6333, + "experience_temperature": 23.3433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:40:08.632992+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.9, + "humidity": 86.2, + "water_total": 1201.0, + "average_temperature": 26.4333, + "experience_temperature": 23.0233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T20:50:06.457316+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 85.9, + "water_total": 1242.0, + "average_temperature": 25.7, + "experience_temperature": 22.93, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:00:06.058406+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 1288.0, + "average_temperature": 25.7667, + "experience_temperature": 23.2367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:10:07.458837+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.4, + "water_total": 1368.0, + "average_temperature": 25.9, + "experience_temperature": 23.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:20:06.843360+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 86.8, + "water_total": 1425.0, + "average_temperature": 25.6333, + "experience_temperature": 23.0433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:30:06.710507+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.1, + "humidity": 87.1, + "water_total": 1489.0, + "average_temperature": 25.3667, + "experience_temperature": 24.9367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:40:06.548465+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.4, + "humidity": 86.9, + "water_total": 1554.0, + "average_temperature": 25.5, + "experience_temperature": 23.98, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T21:50:06.281648+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 85.5, + "water_total": 1625.0, + "average_temperature": 25.5333, + "experience_temperature": 22.3333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:00:06.467722+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.0, + "water_total": 1705.0, + "average_temperature": 25.5, + "experience_temperature": 24.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:10:06.525773+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 86.0, + "water_total": 1705.0, + "average_temperature": 25.5, + "experience_temperature": 24.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:20:06.804704+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 86.9, + "water_total": 1844.0, + "average_temperature": 25.4667, + "experience_temperature": 24.6467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:30:06.884706+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 0.7, + "humidity": 86.5, + "water_total": 1926.0, + "average_temperature": 25.5, + "experience_temperature": 26.35, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:40:06.603978+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.2, + "humidity": 88.0, + "water_total": 2007.0, + "average_temperature": 25.3667, + "experience_temperature": 24.7667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T22:50:06.719506+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 2102.0, + "average_temperature": 25.5333, + "experience_temperature": 23.1633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:00:06.486571+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 87.7, + "water_total": 2168.0, + "average_temperature": 25.5333, + "experience_temperature": 22.7733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:10:06.483370+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.3, + "humidity": 87.4, + "water_total": 2217.0, + "average_temperature": 25.5, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:20:06.784955+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 87.7, + "water_total": 2252.0, + "average_temperature": 25.5667, + "experience_temperature": 22.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:30:06.582933+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 87.7, + "water_total": 2252.0, + "average_temperature": 25.5667, + "experience_temperature": 22.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:40:07.406381+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.8, + "humidity": 87.4, + "water_total": 2331.0, + "average_temperature": 25.5333, + "experience_temperature": 22.7133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-20T23:50:06.807016+07:00", + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.8, + "water_total": 2370.0, + "average_temperature": 25.6, + "experience_temperature": 23.21, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:00:06.212474+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 87.4, + "water_total": 2410.0, + "average_temperature": 25.5333, + "experience_temperature": 23.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:10:06.788673+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 87.1, + "water_total": 2449.0, + "average_temperature": 25.9333, + "experience_temperature": 23.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:20:07.604686+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 2561.0, + "average_temperature": 26.2, + "experience_temperature": 22.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:30:07.089430+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 2664.0, + "average_temperature": 26.1, + "experience_temperature": 23.57, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:40:08.483740+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 2664.0, + "average_temperature": 26.1, + "experience_temperature": 23.57, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T00:50:06.459903+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 87.7, + "water_total": 2798.0, + "average_temperature": 25.9667, + "experience_temperature": 23.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:00:06.533126+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 88.4, + "water_total": 2868.0, + "average_temperature": 26.0, + "experience_temperature": 23.38, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:10:06.678200+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 90.0, + "water_total": 2937.0, + "average_temperature": 26.1667, + "experience_temperature": 23.8667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:20:07.166287+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 87.8, + "water_total": 3017.0, + "average_temperature": 26.1333, + "experience_temperature": 23.3933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:30:06.849928+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 89.8, + "water_total": 3091.0, + "average_temperature": 26.1667, + "experience_temperature": 24.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:40:07.366769+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 3145.0, + "average_temperature": 25.8667, + "experience_temperature": 23.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T01:50:07.153098+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 3183.0, + "average_temperature": 25.8667, + "experience_temperature": 22.9367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:00:07.385791+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 88.9, + "water_total": 3219.0, + "average_temperature": 25.9, + "experience_temperature": 24.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:10:06.726103+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 89.4, + "water_total": 3260.0, + "average_temperature": 26.1333, + "experience_temperature": 24.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:20:07.137427+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 89.4, + "water_total": 3260.0, + "average_temperature": 26.1333, + "experience_temperature": 24.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:30:06.728532+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.7, + "water_total": 3493.0, + "average_temperature": 26.0333, + "experience_temperature": 23.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:40:07.266081+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.2, + "water_total": 3568.0, + "average_temperature": 25.9, + "experience_temperature": 23.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T02:50:06.925014+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 89.6, + "water_total": 3628.0, + "average_temperature": 25.8, + "experience_temperature": 23.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:00:07.382274+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.5, + "water_total": 3696.0, + "average_temperature": 25.7667, + "experience_temperature": 23.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:10:05.487986+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.3, + "water_total": 3775.0, + "average_temperature": 25.9333, + "experience_temperature": 23.4933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:20:05.626838+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.7, + "water_total": 3856.0, + "average_temperature": 25.9, + "experience_temperature": 22.99, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:30:06.002371+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 3913.0, + "average_temperature": 25.9, + "experience_temperature": 23.59, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:40:06.320837+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 4003.0, + "average_temperature": 25.8667, + "experience_temperature": 24.3967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T03:50:05.816662+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.5, + "water_total": 4072.0, + "average_temperature": 25.7667, + "experience_temperature": 23.3667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:00:05.801167+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.5, + "water_total": 4072.0, + "average_temperature": 25.7667, + "experience_temperature": 23.3667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:10:05.678775+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.3, + "humidity": 89.7, + "water_total": 4193.0, + "average_temperature": 25.4333, + "experience_temperature": 24.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:20:06.273613+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.3, + "humidity": 89.6, + "water_total": 4230.0, + "average_temperature": 25.4333, + "experience_temperature": 24.8033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:30:06.020759+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 4268.0, + "average_temperature": 25.4667, + "experience_temperature": 25.2267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:40:06.278692+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.3, + "humidity": 89.1, + "water_total": 4306.0, + "average_temperature": 25.4333, + "experience_temperature": 24.7033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T04:50:05.498135+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.3, + "humidity": 89.2, + "water_total": 4337.0, + "average_temperature": 25.5, + "experience_temperature": 24.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:00:05.969461+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 4375.0, + "average_temperature": 25.5, + "experience_temperature": 25.24, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:10:06.601397+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 90.3, + "water_total": 4413.0, + "average_temperature": 25.6667, + "experience_temperature": 23.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:20:06.878713+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.3, + "water_total": 4497.0, + "average_temperature": 25.9, + "experience_temperature": 23.61, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:30:07.363766+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.2, + "water_total": 4604.0, + "average_temperature": 25.6333, + "experience_temperature": 23.8733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:40:06.626963+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.4, + "water_total": 4675.0, + "average_temperature": 25.6, + "experience_temperature": 23.18, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T05:50:06.460705+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 88.7, + "water_total": 4739.0, + "average_temperature": 25.5333, + "experience_temperature": 22.9733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:00:06.742133+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 88.0, + "water_total": 4809.0, + "average_temperature": 25.8333, + "experience_temperature": 23.8333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:10:08.196117+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.2, + "humidity": 88.5, + "water_total": 4919.0, + "average_temperature": 25.6667, + "experience_temperature": 25.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:20:05.609771+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 89.7, + "water_total": 5005.0, + "average_temperature": 25.4667, + "experience_temperature": 23.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:30:06.375156+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.7, + "water_total": 5097.0, + "average_temperature": 25.5333, + "experience_temperature": 22.6233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:40:06.369000+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.5, + "water_total": 5193.0, + "average_temperature": 25.8333, + "experience_temperature": 23.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T06:50:05.681342+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.3, + "water_total": 5273.0, + "average_temperature": 25.6667, + "experience_temperature": 23.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:00:09.545288+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.3, + "water_total": 5273.0, + "average_temperature": 25.6667, + "experience_temperature": 23.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:10:06.200218+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 5406.0, + "average_temperature": 25.9, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:20:06.707814+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 89.1, + "water_total": 5493.0, + "average_temperature": 26.0333, + "experience_temperature": 23.9033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:30:06.639655+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 89.9, + "water_total": 5602.0, + "average_temperature": 26.8333, + "experience_temperature": 25.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:40:05.337108+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.8, + "water_total": 5711.0, + "average_temperature": 26.4333, + "experience_temperature": 24.2433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T07:50:06.439339+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.3, + "water_total": 5787.0, + "average_temperature": 26.7333, + "experience_temperature": 24.9933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:00:10.032600+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 88.9, + "water_total": 5868.0, + "average_temperature": 27.0667, + "experience_temperature": 24.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:10:06.003989+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 88.9, + "water_total": 5868.0, + "average_temperature": 27.0667, + "experience_temperature": 24.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:20:06.655093+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.0, + "humidity": 87.5, + "water_total": 6039.0, + "average_temperature": 27.6, + "experience_temperature": 24.1, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:30:06.790438+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 86.7, + "water_total": 6117.0, + "average_temperature": 27.9333, + "experience_temperature": 24.6233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:40:05.835967+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 85.4, + "water_total": 6199.0, + "average_temperature": 28.4667, + "experience_temperature": 25.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T08:50:07.257651+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 83.2, + "water_total": 6286.0, + "average_temperature": 28.9, + "experience_temperature": 24.89, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:00:06.111366+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 81.4, + "water_total": 6368.0, + "average_temperature": 29.3667, + "experience_temperature": 23.5967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:10:05.977733+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.1, + "humidity": 78.3, + "water_total": 6448.0, + "average_temperature": 29.7667, + "experience_temperature": 24.0767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:20:06.532935+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 81.1, + "water_total": 6527.0, + "average_temperature": 30.0, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:30:06.022099+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 77.4, + "water_total": 6610.0, + "average_temperature": 30.1667, + "experience_temperature": 22.8967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:40:06.008186+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 77.5, + "water_total": 6684.0, + "average_temperature": 30.5333, + "experience_temperature": 23.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T09:50:06.175209+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 77.5, + "water_total": 6684.0, + "average_temperature": 30.5333, + "experience_temperature": 23.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:00:06.310415+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 76.2, + "water_total": 6873.0, + "average_temperature": 30.7667, + "experience_temperature": 22.9067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:10:05.371311+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 75.1, + "water_total": 6975.0, + "average_temperature": 30.9, + "experience_temperature": 23.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:20:06.036899+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 73.5, + "water_total": 7082.0, + "average_temperature": 31.3667, + "experience_temperature": 22.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:30:06.146046+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.0, + "humidity": 73.0, + "water_total": 7186.0, + "average_temperature": 31.3667, + "experience_temperature": 21.4667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:40:05.554750+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 71.0, + "water_total": 7321.0, + "average_temperature": 31.5333, + "experience_temperature": 21.9333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T10:50:07.144697+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.0, + "humidity": 70.4, + "water_total": 7434.0, + "average_temperature": 31.4667, + "experience_temperature": 21.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:00:07.699220+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 70.7, + "water_total": 7540.0, + "average_temperature": 31.6333, + "experience_temperature": 21.9733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:10:06.311794+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.9, + "humidity": 71.5, + "water_total": 7659.0, + "average_temperature": 31.7, + "experience_temperature": 21.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:20:08.483028+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 69.3, + "water_total": 7789.0, + "average_temperature": 31.8667, + "experience_temperature": 22.9767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:30:06.324195+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.1, + "humidity": 68.8, + "water_total": 7923.0, + "average_temperature": 32.0, + "experience_temperature": 20.91, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:40:05.993353+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 69.7, + "water_total": 8029.0, + "average_temperature": 31.8, + "experience_temperature": 22.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T11:50:06.036344+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 69.7, + "water_total": 8029.0, + "average_temperature": 31.8, + "experience_temperature": 22.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:00:07.336380+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.0, + "humidity": 69.2, + "water_total": 8238.0, + "average_temperature": 31.7, + "experience_temperature": 21.04, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:10:06.637050+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 70.2, + "water_total": 8324.0, + "average_temperature": 31.9667, + "experience_temperature": 22.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:20:07.015161+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 69.0, + "water_total": 8423.0, + "average_temperature": 31.5333, + "experience_temperature": 22.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:30:06.846541+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 68.5, + "water_total": 8521.0, + "average_temperature": 31.7333, + "experience_temperature": 21.6333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:40:05.916740+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 67.3, + "water_total": 8610.0, + "average_temperature": 31.4667, + "experience_temperature": 21.1267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T12:50:05.986188+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 65.6, + "water_total": 8703.0, + "average_temperature": 32.0333, + "experience_temperature": 21.7033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:00:06.413188+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 68.0, + "water_total": 8792.0, + "average_temperature": 32.4, + "experience_temperature": 22.2, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:10:07.298518+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.9, + "humidity": 69.0, + "water_total": 8889.0, + "average_temperature": 32.0333, + "experience_temperature": 21.6833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:20:06.842596+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 68.7, + "water_total": 8990.0, + "average_temperature": 31.7667, + "experience_temperature": 22.0567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:30:06.363581+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 69.0, + "water_total": 9074.0, + "average_temperature": 32.0667, + "experience_temperature": 22.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:40:05.943432+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 68.2, + "water_total": 9168.0, + "average_temperature": 32.1, + "experience_temperature": 22.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T13:50:08.117061+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.0, + "humidity": 66.7, + "water_total": 9263.0, + "average_temperature": 32.0667, + "experience_temperature": 20.9067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T14:10:05.783261+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.2, + "humidity": 70.4, + "water_total": 9455.0, + "average_temperature": 31.8, + "experience_temperature": 20.68, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T14:20:05.952927+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 74.6, + "water_total": 9546.0, + "average_temperature": 31.8333, + "experience_temperature": 23.6533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T14:30:05.268072+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 73.7, + "water_total": 9641.0, + "average_temperature": 31.8333, + "experience_temperature": 23.4733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T14:40:07.080718+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 75.0, + "water_total": 9734.0, + "average_temperature": 31.7, + "experience_temperature": 23.6, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T14:50:05.689954+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 3.1, + "humidity": 74.7, + "water_total": 9824.0, + "average_temperature": 31.5333, + "experience_temperature": 21.6233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T15:10:06.155929+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 74.2, + "water_total": 9988.0, + "average_temperature": 30.9333, + "experience_temperature": 22.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T15:20:06.074927+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 74.2, + "water_total": 9988.0, + "average_temperature": 30.9333, + "experience_temperature": 22.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T15:30:06.340302+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 74.6, + "water_total": 10156.0, + "average_temperature": 31.0667, + "experience_temperature": 22.1867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T15:40:05.443061+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 72.8, + "water_total": 10229.0, + "average_temperature": 31.1667, + "experience_temperature": 22.6267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T15:50:05.709091+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 72.8, + "water_total": 10307.0, + "average_temperature": 31.2667, + "experience_temperature": 22.7267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T16:10:05.769008+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.5, + "humidity": 73.4, + "water_total": 10391.0, + "average_temperature": 31.0667, + "experience_temperature": 22.9967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T16:20:05.963083+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 74.0, + "water_total": 10574.0, + "average_temperature": 31.3667, + "experience_temperature": 23.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T16:30:06.206883+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.9, + "humidity": 73.8, + "water_total": 10659.0, + "average_temperature": 31.0333, + "experience_temperature": 21.6433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T16:40:05.898199+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 76.4, + "water_total": 10752.0, + "average_temperature": 30.7333, + "experience_temperature": 22.2133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T16:50:06.225611+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.6, + "humidity": 76.8, + "water_total": 10849.0, + "average_temperature": 30.7, + "experience_temperature": 22.96, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T17:10:05.161797+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 77.5, + "water_total": 79.0, + "average_temperature": 30.3667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T17:20:06.351868+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 77.5, + "water_total": 79.0, + "average_temperature": 30.3667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T17:30:06.163163+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.8, + "humidity": 77.5, + "water_total": 236.0, + "average_temperature": 30.3, + "experience_temperature": 22.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T17:40:08.491610+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.7, + "humidity": 77.6, + "water_total": 312.0, + "average_temperature": 30.2, + "experience_temperature": 22.27, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T17:50:06.386058+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.1, + "humidity": 77.4, + "water_total": 393.0, + "average_temperature": 30.1667, + "experience_temperature": 24.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:00:06.185332+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 79.0, + "water_total": 458.0, + "average_temperature": 28.7667, + "experience_temperature": 22.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:10:06.152617+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 80.9, + "water_total": 532.0, + "average_temperature": 28.5, + "experience_temperature": 24.38, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:20:06.386055+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.0, + "humidity": 83.2, + "water_total": 592.0, + "average_temperature": 27.6667, + "experience_temperature": 23.3067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:30:06.435631+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 84.9, + "water_total": 655.0, + "average_temperature": 27.2667, + "experience_temperature": 24.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:40:05.670023+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 85.4, + "water_total": 713.0, + "average_temperature": 27.4333, + "experience_temperature": 24.2133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T18:50:09.752700+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 85.6, + "water_total": 790.0, + "average_temperature": 27.3, + "experience_temperature": 24.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:00:06.102900+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 85.1, + "water_total": 887.0, + "average_temperature": 27.0667, + "experience_temperature": 24.8367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:10:05.420401+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.0, + "humidity": 87.7, + "water_total": 973.0, + "average_temperature": 27.1, + "experience_temperature": 23.64, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:20:06.267523+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 86.1, + "water_total": 1030.0, + "average_temperature": 26.8333, + "experience_temperature": 23.7533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:30:06.550244+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 86.5, + "water_total": 1099.0, + "average_temperature": 27.1, + "experience_temperature": 24.8, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:40:07.148277+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 86.5, + "water_total": 1170.0, + "average_temperature": 27.0667, + "experience_temperature": 24.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T19:50:05.860083+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 86.9, + "water_total": 1252.0, + "average_temperature": 26.8333, + "experience_temperature": 23.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:00:06.042442+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 87.9, + "water_total": 1311.0, + "average_temperature": 26.9, + "experience_temperature": 24.18, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:10:05.096110+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 87.9, + "water_total": 1311.0, + "average_temperature": 26.9, + "experience_temperature": 24.18, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:20:06.026672+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 87.8, + "water_total": 1426.0, + "average_temperature": 27.0333, + "experience_temperature": 23.9433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:30:06.094316+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.8, + "humidity": 87.4, + "water_total": 1500.0, + "average_temperature": 26.9, + "experience_temperature": 24.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:40:06.401634+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 87.9, + "water_total": 1564.0, + "average_temperature": 26.8333, + "experience_temperature": 23.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T20:50:05.466581+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.2, + "humidity": 88.9, + "water_total": 1611.0, + "average_temperature": 26.7667, + "experience_temperature": 22.8467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:00:05.837376+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.3, + "humidity": 87.5, + "water_total": 1655.0, + "average_temperature": 26.8, + "experience_temperature": 22.25, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:10:05.620480+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.0, + "humidity": 87.8, + "water_total": 1701.0, + "average_temperature": 26.9, + "experience_temperature": 23.46, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:20:06.419405+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.2, + "humidity": 89.0, + "water_total": 1754.0, + "average_temperature": 26.9, + "experience_temperature": 23.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:30:05.800520+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 2.0, + "humidity": 88.8, + "water_total": 1807.0, + "average_temperature": 26.9, + "experience_temperature": 23.66, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:40:06.941240+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.1, + "water_total": 1855.0, + "average_temperature": 26.9667, + "experience_temperature": 23.9367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T21:50:06.353826+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.1, + "water_total": 1855.0, + "average_temperature": 26.9667, + "experience_temperature": 23.9367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:00:06.912751+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.4, + "water_total": 1976.0, + "average_temperature": 27.0333, + "experience_temperature": 24.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:10:08.999701+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 88.6, + "water_total": 2025.0, + "average_temperature": 26.9667, + "experience_temperature": 25.0867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:20:05.652683+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 88.4, + "water_total": 2085.0, + "average_temperature": 27.0333, + "experience_temperature": 24.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:30:06.269006+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 2142.0, + "average_temperature": 27.1, + "experience_temperature": 24.35, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:40:06.018421+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.4, + "humidity": 89.6, + "water_total": 2198.0, + "average_temperature": 27.2667, + "experience_temperature": 26.2867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T22:50:06.269867+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 88.5, + "water_total": 2276.0, + "average_temperature": 27.2333, + "experience_temperature": 24.9833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:00:06.083493+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.9, + "humidity": 89.2, + "water_total": 2352.0, + "average_temperature": 26.9, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:10:06.424418+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.4, + "humidity": 89.2, + "water_total": 2388.0, + "average_temperature": 26.6, + "experience_temperature": 25.54, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:20:08.059166+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 90.1, + "water_total": 2412.0, + "average_temperature": 26.6333, + "experience_temperature": 25.4033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:30:05.906557+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.7, + "humidity": 89.8, + "water_total": 2433.0, + "average_temperature": 26.6667, + "experience_temperature": 24.6767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:40:06.489429+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.5, + "humidity": 89.4, + "water_total": 2454.0, + "average_temperature": 26.5667, + "experience_temperature": 25.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-21T23:50:09.637910+07:00", + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.7, + "water_total": 2477.0, + "average_temperature": 26.6, + "experience_temperature": 24.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:00:06.024614+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 90.2, + "water_total": 2501.0, + "average_temperature": 26.6333, + "experience_temperature": 25.0733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:10:06.312950+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.3, + "water_total": 2522.0, + "average_temperature": 26.9667, + "experience_temperature": 24.5267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:20:05.395592+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.3, + "water_total": 2522.0, + "average_temperature": 26.9667, + "experience_temperature": 24.5267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:30:05.848900+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.0, + "water_total": 2604.0, + "average_temperature": 26.9667, + "experience_temperature": 23.9167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:40:06.031735+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.5, + "humidity": 89.3, + "water_total": 2722.0, + "average_temperature": 26.6667, + "experience_temperature": 25.2767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T00:50:06.621610+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 88.7, + "water_total": 2763.0, + "average_temperature": 26.6667, + "experience_temperature": 24.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:00:05.991885+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.4, + "water_total": 2815.0, + "average_temperature": 26.7667, + "experience_temperature": 24.3467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:10:06.490950+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 88.1, + "water_total": 2864.0, + "average_temperature": 26.8667, + "experience_temperature": 22.7867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:20:06.244791+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.4, + "water_total": 2948.0, + "average_temperature": 26.9333, + "experience_temperature": 24.6633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:30:05.576634+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 3013.0, + "average_temperature": 26.7667, + "experience_temperature": 23.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:40:05.935041+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.3, + "water_total": 3087.0, + "average_temperature": 26.8333, + "experience_temperature": 24.5433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T01:50:05.985054+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.4, + "water_total": 3165.0, + "average_temperature": 27.0333, + "experience_temperature": 24.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:00:07.526414+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.4, + "water_total": 3272.0, + "average_temperature": 26.8667, + "experience_temperature": 24.4467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:10:06.401540+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 89.8, + "water_total": 3344.0, + "average_temperature": 26.7333, + "experience_temperature": 24.7433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:20:06.199744+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.4, + "humidity": 90.0, + "water_total": 3411.0, + "average_temperature": 26.6667, + "experience_temperature": 25.7667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:30:08.934319+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 89.3, + "water_total": 3484.0, + "average_temperature": 26.6667, + "experience_temperature": 24.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:40:08.498150+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 89.3, + "water_total": 3556.0, + "average_temperature": 26.6667, + "experience_temperature": 24.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T02:50:06.130854+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 89.7, + "water_total": 3619.0, + "average_temperature": 26.8, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:00:05.997468+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 89.6, + "water_total": 3684.0, + "average_temperature": 26.6667, + "experience_temperature": 24.9867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:10:06.034983+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.5, + "humidity": 90.1, + "water_total": 3744.0, + "average_temperature": 26.6667, + "experience_temperature": 25.4367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:20:08.601913+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 3802.0, + "average_temperature": 26.8, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:30:06.554353+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 3802.0, + "average_temperature": 26.8, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:40:06.062686+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 3802.0, + "average_temperature": 26.8, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T03:50:05.944638+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 3982.0, + "average_temperature": 26.8333, + "experience_temperature": 24.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:00:06.086026+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 89.6, + "water_total": 4034.0, + "average_temperature": 26.7667, + "experience_temperature": 23.6867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:10:07.173230+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.5, + "humidity": 89.5, + "water_total": 4069.0, + "average_temperature": 26.5, + "experience_temperature": 25.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:20:06.186664+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.8, + "water_total": 4090.0, + "average_temperature": 26.6, + "experience_temperature": 24.26, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:30:06.352559+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.5, + "water_total": 4111.0, + "average_temperature": 26.6667, + "experience_temperature": 24.2667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:40:06.157640+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 89.7, + "water_total": 4132.0, + "average_temperature": 26.7, + "experience_temperature": 24.69, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T04:50:07.369686+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 89.9, + "water_total": 4157.0, + "average_temperature": 26.7, + "experience_temperature": 25.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:00:06.983467+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.9, + "water_total": 4180.0, + "average_temperature": 26.7333, + "experience_temperature": 24.4133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:10:06.824151+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 89.7, + "water_total": 4260.0, + "average_temperature": 27.1333, + "experience_temperature": 24.4233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:20:06.121973+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 89.0, + "water_total": 4386.0, + "average_temperature": 26.9333, + "experience_temperature": 23.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:30:06.708195+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 89.2, + "water_total": 4465.0, + "average_temperature": 26.7, + "experience_temperature": 24.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:40:06.461342+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.5, + "humidity": 89.4, + "water_total": 4528.0, + "average_temperature": 26.6667, + "experience_temperature": 25.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T05:50:06.430049+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 88.7, + "water_total": 4594.0, + "average_temperature": 26.6667, + "experience_temperature": 24.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:00:07.144187+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.4, + "water_total": 4653.0, + "average_temperature": 26.7333, + "experience_temperature": 24.3133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:10:06.713802+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.5, + "humidity": 89.6, + "water_total": 4708.0, + "average_temperature": 26.6667, + "experience_temperature": 25.3367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:20:06.457818+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 4768.0, + "average_temperature": 26.7667, + "experience_temperature": 24.0167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:30:06.409141+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 89.5, + "water_total": 4836.0, + "average_temperature": 26.8667, + "experience_temperature": 24.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:40:06.209357+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 89.6, + "water_total": 4902.0, + "average_temperature": 26.7, + "experience_temperature": 22.92, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T06:50:07.359492+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 4965.0, + "average_temperature": 26.7, + "experience_temperature": 24.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:00:06.085267+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 4965.0, + "average_temperature": 26.7, + "experience_temperature": 24.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:10:05.824187+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 91.9, + "water_total": 5066.0, + "average_temperature": 26.7, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:20:06.392565+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 91.2, + "water_total": 5108.0, + "average_temperature": 26.8333, + "experience_temperature": 23.7233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:30:06.185028+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 90.3, + "water_total": 5158.0, + "average_temperature": 26.8333, + "experience_temperature": 24.2433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:40:07.745304+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 89.9, + "water_total": 5213.0, + "average_temperature": 26.9, + "experience_temperature": 24.23, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T07:50:06.338486+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 89.3, + "water_total": 5269.0, + "average_temperature": 26.8, + "experience_temperature": 23.66, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:00:09.507209+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.4, + "water_total": 5312.0, + "average_temperature": 26.9, + "experience_temperature": 24.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:10:08.306621+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.4, + "water_total": 5312.0, + "average_temperature": 26.9, + "experience_temperature": 24.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:20:07.513610+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 87.0, + "water_total": 5417.0, + "average_temperature": 27.3333, + "experience_temperature": 23.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:30:06.993648+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 85.6, + "water_total": 5496.0, + "average_temperature": 27.6667, + "experience_temperature": 24.1367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:40:08.638206+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 84.6, + "water_total": 5555.0, + "average_temperature": 28.0, + "experience_temperature": 24.62, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T08:50:06.235606+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 83.1, + "water_total": 5614.0, + "average_temperature": 28.2, + "experience_temperature": 23.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:00:06.585493+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 83.1, + "water_total": 5614.0, + "average_temperature": 28.2, + "experience_temperature": 23.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:10:06.466482+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 81.7, + "water_total": 5742.0, + "average_temperature": 28.7667, + "experience_temperature": 23.7567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:20:07.060206+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 80.7, + "water_total": 5799.0, + "average_temperature": 29.4333, + "experience_temperature": 23.1733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:30:06.229864+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 78.4, + "water_total": 5857.0, + "average_temperature": 29.6333, + "experience_temperature": 21.5133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:40:06.566175+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 77.8, + "water_total": 5915.0, + "average_temperature": 29.9667, + "experience_temperature": 22.4267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T09:50:07.485027+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.3, + "humidity": 78.4, + "water_total": 5968.0, + "average_temperature": 29.6333, + "experience_temperature": 23.2633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:00:06.671259+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 77.7, + "water_total": 6028.0, + "average_temperature": 29.6667, + "experience_temperature": 22.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:10:07.599814+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.3, + "humidity": 79.2, + "water_total": 6085.0, + "average_temperature": 29.5, + "experience_temperature": 23.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:20:08.662984+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 77.3, + "water_total": 6145.0, + "average_temperature": 29.8, + "experience_temperature": 22.16, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:30:06.672909+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 76.7, + "water_total": 6203.0, + "average_temperature": 29.9333, + "experience_temperature": 22.1733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:40:06.579077+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 76.0, + "water_total": 6282.0, + "average_temperature": 30.1667, + "experience_temperature": 23.6667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T10:50:09.337057+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 76.5, + "water_total": 6353.0, + "average_temperature": 30.4, + "experience_temperature": 23.3, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:00:08.869477+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.3, + "humidity": 75.1, + "water_total": 6432.0, + "average_temperature": 30.5333, + "experience_temperature": 23.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:10:07.391430+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 74.1, + "water_total": 6499.0, + "average_temperature": 30.7333, + "experience_temperature": 22.8033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:20:06.718359+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.3, + "humidity": 74.2, + "water_total": 6568.0, + "average_temperature": 31.2, + "experience_temperature": 23.99, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:30:07.131021+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.0, + "humidity": 71.8, + "water_total": 6653.0, + "average_temperature": 31.4333, + "experience_temperature": 21.2933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:40:07.190469+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.7, + "humidity": 71.7, + "water_total": 6737.0, + "average_temperature": 31.2333, + "experience_temperature": 22.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T11:50:06.701142+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 69.7, + "water_total": 6804.0, + "average_temperature": 31.5333, + "experience_temperature": 23.0733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:00:09.804717+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.0, + "humidity": 70.4, + "water_total": 6884.0, + "average_temperature": 31.3667, + "experience_temperature": 20.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:10:07.284740+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 71.0, + "water_total": 6953.0, + "average_temperature": 31.1333, + "experience_temperature": 22.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:20:07.285019+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 71.6, + "water_total": 7018.0, + "average_temperature": 31.4667, + "experience_temperature": 23.3867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:30:09.356319+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.7, + "humidity": 68.4, + "water_total": 7079.0, + "average_temperature": 31.3333, + "experience_temperature": 21.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:40:08.019343+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 71.2, + "water_total": 7156.0, + "average_temperature": 31.8333, + "experience_temperature": 22.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T12:50:07.945154+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.1, + "humidity": 73.0, + "water_total": 7217.0, + "average_temperature": 31.6333, + "experience_temperature": 21.3833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:00:07.261742+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.2, + "humidity": 71.9, + "water_total": 7273.0, + "average_temperature": 31.0667, + "experience_temperature": 20.2467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:10:08.059585+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.9, + "humidity": 72.5, + "water_total": 7346.0, + "average_temperature": 31.6333, + "experience_temperature": 21.9833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:20:06.835374+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 71.2, + "water_total": 7413.0, + "average_temperature": 31.5, + "experience_temperature": 21.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:30:06.733200+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.4, + "humidity": 73.0, + "water_total": 7482.0, + "average_temperature": 31.5333, + "experience_temperature": 23.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:40:07.211693+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.7, + "humidity": 70.4, + "water_total": 7547.0, + "average_temperature": 31.5667, + "experience_temperature": 22.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T13:50:07.757536+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 69.0, + "water_total": 7606.0, + "average_temperature": 31.6333, + "experience_temperature": 22.6833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T14:10:06.527670+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.0, + "humidity": 70.6, + "water_total": 7722.0, + "average_temperature": 31.9333, + "experience_temperature": 21.5533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T14:20:06.705410+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 71.0, + "water_total": 7796.0, + "average_temperature": 31.4667, + "experience_temperature": 22.9167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T14:30:08.797120+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 68.2, + "water_total": 7852.0, + "average_temperature": 31.2333, + "experience_temperature": 21.7733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T14:40:07.942164+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.7, + "humidity": 67.0, + "water_total": 7906.0, + "average_temperature": 31.7667, + "experience_temperature": 21.7167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T14:50:07.058980+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 67.8, + "water_total": 7969.0, + "average_temperature": 31.7, + "experience_temperature": 21.46, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T15:10:07.580832+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 76.0, + "water_total": 8106.0, + "average_temperature": 31.4333, + "experience_temperature": 23.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T15:20:08.083518+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 77.2, + "water_total": 8172.0, + "average_temperature": 30.8667, + "experience_temperature": 23.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T15:30:08.271777+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 77.2, + "water_total": 8172.0, + "average_temperature": 30.8667, + "experience_temperature": 23.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T15:40:07.965987+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 75.7, + "water_total": 8273.0, + "average_temperature": 30.6, + "experience_temperature": 22.99, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T15:50:07.873399+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 3.2, + "humidity": 75.4, + "water_total": 8312.0, + "average_temperature": 30.8667, + "experience_temperature": 20.7467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T16:10:07.293430+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.9, + "humidity": 73.5, + "water_total": 8410.0, + "average_temperature": 31.2333, + "experience_temperature": 21.7833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T16:20:06.861314+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 74.2, + "water_total": 8472.0, + "average_temperature": 31.2333, + "experience_temperature": 22.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T16:30:10.790606+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.6, + "humidity": 73.3, + "water_total": 8534.0, + "average_temperature": 30.8667, + "experience_temperature": 22.4267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T16:40:08.535524+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 75.7, + "water_total": 8592.0, + "average_temperature": 30.7333, + "experience_temperature": 23.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T16:50:06.853673+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 73.9, + "water_total": 8647.0, + "average_temperature": 30.5667, + "experience_temperature": 22.5967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T17:10:06.514676+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.8, + "humidity": 73.3, + "water_total": 57.0, + "average_temperature": 30.0667, + "experience_temperature": 20.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T17:20:09.586363+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 76.0, + "water_total": 116.0, + "average_temperature": 29.1333, + "experience_temperature": 21.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T17:30:06.390955+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 79.8, + "water_total": 162.0, + "average_temperature": 28.6333, + "experience_temperature": 23.5933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T17:40:08.003613+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 84.4, + "water_total": 204.0, + "average_temperature": 28.5667, + "experience_temperature": 22.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T17:50:09.574081+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.5, + "humidity": 84.4, + "water_total": 204.0, + "average_temperature": 28.5667, + "experience_temperature": 22.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:00:07.187471+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 84.0, + "water_total": 356.0, + "average_temperature": 28.3667, + "experience_temperature": 24.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:10:08.000935+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 85.7, + "water_total": 424.0, + "average_temperature": 28.0333, + "experience_temperature": 25.2233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:20:08.140079+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 85.9, + "water_total": 475.0, + "average_temperature": 27.6667, + "experience_temperature": 23.8467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:30:06.633790+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 86.6, + "water_total": 496.0, + "average_temperature": 27.3667, + "experience_temperature": 23.6867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:40:05.596889+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 87.2, + "water_total": 512.0, + "average_temperature": 27.5333, + "experience_temperature": 24.6733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T18:50:05.807865+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 86.1, + "water_total": 617.0, + "average_temperature": 27.6667, + "experience_temperature": 24.2367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:00:05.834343+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 86.6, + "water_total": 680.0, + "average_temperature": 27.4333, + "experience_temperature": 23.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:10:05.753509+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 86.6, + "water_total": 680.0, + "average_temperature": 27.4333, + "experience_temperature": 23.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:20:05.394323+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.3, + "humidity": 87.6, + "water_total": 795.0, + "average_temperature": 27.5, + "experience_temperature": 22.97, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:30:10.892192+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.1, + "water_total": 846.0, + "average_temperature": 27.4, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:40:06.040949+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 87.8, + "water_total": 902.0, + "average_temperature": 27.6333, + "experience_temperature": 25.5933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T19:50:05.773482+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.2, + "water_total": 962.0, + "average_temperature": 27.4667, + "experience_temperature": 24.2567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:00:08.597824+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 87.3, + "water_total": 1017.0, + "average_temperature": 27.4667, + "experience_temperature": 23.9267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:10:06.671819+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.2, + "water_total": 1075.0, + "average_temperature": 27.5667, + "experience_temperature": 24.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:20:06.215307+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.2, + "water_total": 1075.0, + "average_temperature": 27.5667, + "experience_temperature": 24.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:30:05.469967+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.7, + "humidity": 88.9, + "water_total": 1190.0, + "average_temperature": 27.6, + "experience_temperature": 25.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:40:06.201053+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 87.5, + "water_total": 1247.0, + "average_temperature": 27.5667, + "experience_temperature": 24.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T20:50:05.443058+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.4, + "water_total": 1302.0, + "average_temperature": 27.4667, + "experience_temperature": 24.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:00:05.775789+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 87.1, + "water_total": 1362.0, + "average_temperature": 27.0667, + "experience_temperature": 23.4867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:10:08.013330+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 86.7, + "water_total": 1417.0, + "average_temperature": 27.2333, + "experience_temperature": 24.2733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:20:06.898903+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.3, + "water_total": 1476.0, + "average_temperature": 26.9667, + "experience_temperature": 23.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:30:06.430343+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 89.5, + "water_total": 1525.0, + "average_temperature": 27.0667, + "experience_temperature": 24.6667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:40:05.401302+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 1568.0, + "average_temperature": 26.8667, + "experience_temperature": 23.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T21:50:05.671144+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 1568.0, + "average_temperature": 26.8667, + "experience_temperature": 23.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:00:06.463256+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 84.8, + "water_total": 1694.0, + "average_temperature": 27.2, + "experience_temperature": 22.81, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:10:05.884603+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 86.5, + "water_total": 1757.0, + "average_temperature": 27.1667, + "experience_temperature": 24.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:20:05.896926+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.6, + "humidity": 87.1, + "water_total": 1827.0, + "average_temperature": 27.0667, + "experience_temperature": 24.8867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:30:06.606697+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.2, + "humidity": 87.7, + "water_total": 1904.0, + "average_temperature": 27.0, + "experience_temperature": 22.84, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:40:06.961417+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 87.5, + "water_total": 1975.0, + "average_temperature": 26.8, + "experience_temperature": 22.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T22:50:05.463375+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.1, + "humidity": 87.5, + "water_total": 1975.0, + "average_temperature": 26.8, + "experience_temperature": 22.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:00:06.104217+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 87.7, + "water_total": 2079.0, + "average_temperature": 26.8333, + "experience_temperature": 23.7233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:10:05.711278+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 87.3, + "water_total": 2135.0, + "average_temperature": 26.9667, + "experience_temperature": 24.1267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:20:06.033414+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 2.0, + "humidity": 87.9, + "water_total": 2165.0, + "average_temperature": 26.6333, + "experience_temperature": 23.2133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:30:05.935018+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.8, + "humidity": 88.8, + "water_total": 2185.0, + "average_temperature": 26.6, + "experience_temperature": 24.06, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:40:06.230952+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.7, + "water_total": 2203.0, + "average_temperature": 26.7667, + "experience_temperature": 23.8567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-22T23:50:06.379271+07:00", + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 2221.0, + "average_temperature": 26.8, + "experience_temperature": 23.87, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:00:07.045662+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.2, + "water_total": 2241.0, + "average_temperature": 26.7, + "experience_temperature": 23.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:10:06.067397+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.2, + "water_total": 2241.0, + "average_temperature": 26.7, + "experience_temperature": 23.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:20:05.975532+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.1, + "water_total": 2367.0, + "average_temperature": 27.1333, + "experience_temperature": 24.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:30:05.417885+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 2446.0, + "average_temperature": 26.8, + "experience_temperature": 24.49, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:40:06.109356+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.3, + "water_total": 2500.0, + "average_temperature": 26.8667, + "experience_temperature": 23.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T00:50:06.244327+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.2, + "water_total": 2545.0, + "average_temperature": 26.8333, + "experience_temperature": 23.4733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:00:05.829883+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 2590.0, + "average_temperature": 26.8333, + "experience_temperature": 24.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:10:05.686375+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 2590.0, + "average_temperature": 26.8333, + "experience_temperature": 24.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:20:06.060959+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.2, + "water_total": 2699.0, + "average_temperature": 26.8667, + "experience_temperature": 23.8567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:30:06.598469+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.3, + "water_total": 2746.0, + "average_temperature": 26.9, + "experience_temperature": 23.91, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:40:05.872466+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 88.7, + "water_total": 2779.0, + "average_temperature": 26.6333, + "experience_temperature": 24.0733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T01:50:06.294359+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 89.5, + "water_total": 2799.0, + "average_temperature": 26.6333, + "experience_temperature": 23.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:00:05.919125+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 2815.0, + "average_temperature": 26.6, + "experience_temperature": 23.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:10:06.023638+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.2, + "water_total": 2835.0, + "average_temperature": 26.9333, + "experience_temperature": 24.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:20:06.432186+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.0, + "water_total": 2910.0, + "average_temperature": 27.0667, + "experience_temperature": 24.0167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:30:05.891502+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 88.7, + "water_total": 3004.0, + "average_temperature": 26.8333, + "experience_temperature": 24.6233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:40:05.869573+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 3062.0, + "average_temperature": 26.7, + "experience_temperature": 23.95, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T02:50:07.330362+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.7, + "water_total": 3107.0, + "average_temperature": 26.7, + "experience_temperature": 23.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T03:00:05.834589+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.6, + "humidity": 88.9, + "water_total": 3150.0, + "average_temperature": 26.7, + "experience_temperature": 24.88, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T03:10:05.688271+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 3204.0, + "average_temperature": 26.7, + "experience_temperature": 23.81, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T03:20:06.019247+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 3245.0, + "average_temperature": 26.6667, + "experience_temperature": 23.7367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T03:30:05.559545+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 3305.0, + "average_temperature": 26.6667, + "experience_temperature": 23.8367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T03:50:06.352746+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.0, + "water_total": 3402.0, + "average_temperature": 26.7, + "experience_temperature": 23.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:00:06.363206+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 89.2, + "water_total": 3447.0, + "average_temperature": 26.7333, + "experience_temperature": 23.5733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:10:05.687999+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 89.0, + "water_total": 3483.0, + "average_temperature": 26.5667, + "experience_temperature": 24.4167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:20:06.028643+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 89.4, + "water_total": 3503.0, + "average_temperature": 26.5333, + "experience_temperature": 23.4133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:30:06.367878+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.8, + "water_total": 3522.0, + "average_temperature": 26.6667, + "experience_temperature": 23.9767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:40:06.390633+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.3, + "water_total": 3539.0, + "average_temperature": 26.5667, + "experience_temperature": 23.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T04:50:06.002626+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.1, + "humidity": 89.5, + "water_total": 3559.0, + "average_temperature": 26.6, + "experience_temperature": 23.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T05:00:05.975962+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.7, + "water_total": 3578.0, + "average_temperature": 26.6667, + "experience_temperature": 23.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T05:10:06.076567+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 89.4, + "water_total": 3595.0, + "average_temperature": 27.0, + "experience_temperature": 24.93, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T05:20:06.003218+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.2, + "water_total": 3679.0, + "average_temperature": 27.1, + "experience_temperature": 24.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T05:30:06.274765+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.9, + "water_total": 3770.0, + "average_temperature": 26.8667, + "experience_temperature": 24.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T05:40:06.429015+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 89.9, + "water_total": 3827.0, + "average_temperature": 26.7333, + "experience_temperature": 24.4133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T06:00:05.626025+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.6, + "humidity": 89.0, + "water_total": 3939.0, + "average_temperature": 27.1, + "experience_temperature": 25.3, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T06:10:06.706444+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 4014.0, + "average_temperature": 26.8, + "experience_temperature": 24.05, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T06:30:06.554777+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 90.3, + "water_total": 4202.0, + "average_temperature": 26.7, + "experience_temperature": 22.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T06:40:07.068291+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 89.5, + "water_total": 4263.0, + "average_temperature": 26.5333, + "experience_temperature": 23.4333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T06:50:06.676742+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 90.2, + "water_total": 4326.0, + "average_temperature": 26.6333, + "experience_temperature": 23.6733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:00:05.690110+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 90.2, + "water_total": 4326.0, + "average_temperature": 26.6333, + "experience_temperature": 23.6733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:10:06.388322+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 90.6, + "water_total": 4461.0, + "average_temperature": 27.0, + "experience_temperature": 24.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:20:07.321088+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 89.9, + "water_total": 4518.0, + "average_temperature": 27.0, + "experience_temperature": 24.68, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:30:06.308447+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 89.9, + "water_total": 4518.0, + "average_temperature": 27.0, + "experience_temperature": 24.68, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:40:06.394862+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 89.7, + "water_total": 4649.0, + "average_temperature": 27.5, + "experience_temperature": 24.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T07:50:07.554098+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.4, + "water_total": 4706.0, + "average_temperature": 27.2, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:00:05.984265+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.4, + "water_total": 4706.0, + "average_temperature": 27.2, + "experience_temperature": 24.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:10:06.670992+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 89.4, + "water_total": 4771.0, + "average_temperature": 27.5, + "experience_temperature": 23.68, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:20:06.649679+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 88.9, + "water_total": 4838.0, + "average_temperature": 27.8333, + "experience_temperature": 23.9133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:30:08.919467+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 85.9, + "water_total": 4954.0, + "average_temperature": 28.8667, + "experience_temperature": 22.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:40:06.802027+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.8, + "humidity": 84.0, + "water_total": 5013.0, + "average_temperature": 28.8667, + "experience_temperature": 21.8667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T08:50:06.734421+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 83.1, + "water_total": 5066.0, + "average_temperature": 29.1, + "experience_temperature": 23.32, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:00:06.283080+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.7, + "humidity": 83.1, + "water_total": 5123.0, + "average_temperature": 29.0, + "experience_temperature": 22.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:10:05.825708+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 82.0, + "water_total": 5180.0, + "average_temperature": 28.8667, + "experience_temperature": 22.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:20:06.912891+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 81.2, + "water_total": 5248.0, + "average_temperature": 29.2333, + "experience_temperature": 22.3733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:30:06.817925+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 80.1, + "water_total": 5313.0, + "average_temperature": 29.3333, + "experience_temperature": 25.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:40:08.165390+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 77.8, + "water_total": 5381.0, + "average_temperature": 29.5333, + "experience_temperature": 21.9933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T09:50:07.470032+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 77.2, + "water_total": 5453.0, + "average_temperature": 29.7667, + "experience_temperature": 22.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:00:11.638116+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 78.5, + "water_total": 5534.0, + "average_temperature": 29.8, + "experience_temperature": 22.75, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:10:06.509859+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 77.9, + "water_total": 5593.0, + "average_temperature": 29.8667, + "experience_temperature": 22.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:20:06.822144+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 77.9, + "water_total": 5593.0, + "average_temperature": 29.8667, + "experience_temperature": 22.6967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:30:06.312047+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 72.8, + "water_total": 5699.0, + "average_temperature": 30.7333, + "experience_temperature": 22.5433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:40:06.544415+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.9, + "humidity": 71.9, + "water_total": 5778.0, + "average_temperature": 30.9667, + "experience_temperature": 21.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T10:50:07.489900+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.9, + "humidity": 71.6, + "water_total": 5856.0, + "average_temperature": 31.0, + "experience_temperature": 21.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:00:06.419918+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 3.1, + "humidity": 73.6, + "water_total": 5930.0, + "average_temperature": 30.9667, + "experience_temperature": 20.8367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:10:11.092647+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.8, + "humidity": 73.9, + "water_total": 6007.0, + "average_temperature": 30.7667, + "experience_temperature": 21.7467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:20:06.867596+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 73.9, + "water_total": 6084.0, + "average_temperature": 30.8, + "experience_temperature": 22.83, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:30:06.890456+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 73.8, + "water_total": 6162.0, + "average_temperature": 30.7, + "experience_temperature": 22.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:40:06.385759+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 73.8, + "water_total": 6238.0, + "average_temperature": 31.1333, + "experience_temperature": 23.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T11:50:07.792258+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 73.8, + "water_total": 6238.0, + "average_temperature": 31.1333, + "experience_temperature": 23.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:00:07.350277+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 3.0, + "humidity": 72.9, + "water_total": 6362.0, + "average_temperature": 30.7333, + "experience_temperature": 20.8133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:10:06.848383+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 3.1, + "humidity": 72.6, + "water_total": 6422.0, + "average_temperature": 31.2333, + "experience_temperature": 20.9033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:20:07.046204+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 73.5, + "water_total": 6482.0, + "average_temperature": 30.6, + "experience_temperature": 22.9, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:30:06.973625+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 3.2, + "humidity": 73.4, + "water_total": 6543.0, + "average_temperature": 31.0333, + "experience_temperature": 20.5133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:40:07.558727+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.8, + "humidity": 72.8, + "water_total": 6611.0, + "average_temperature": 31.1, + "experience_temperature": 21.86, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T12:50:08.202760+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.8, + "humidity": 72.9, + "water_total": 6670.0, + "average_temperature": 31.0333, + "experience_temperature": 21.8133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:00:06.683383+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.9, + "humidity": 73.7, + "water_total": 6741.0, + "average_temperature": 31.2333, + "experience_temperature": 21.8233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:10:07.175217+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.7, + "humidity": 75.4, + "water_total": 6803.0, + "average_temperature": 30.5333, + "experience_temperature": 22.1633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:20:08.275804+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 75.3, + "water_total": 6862.0, + "average_temperature": 30.3667, + "experience_temperature": 23.0267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:30:09.750606+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 76.3, + "water_total": 6918.0, + "average_temperature": 30.3, + "experience_temperature": 22.81, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:40:11.201553+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.9, + "humidity": 78.7, + "water_total": 6974.0, + "average_temperature": 30.3667, + "experience_temperature": 21.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T13:50:07.683700+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 77.0, + "water_total": 7021.0, + "average_temperature": 30.1667, + "experience_temperature": 22.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T14:10:10.032890+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 76.5, + "water_total": 7135.0, + "average_temperature": 30.5333, + "experience_temperature": 23.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T14:20:07.299507+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 79.4, + "water_total": 7192.0, + "average_temperature": 29.2667, + "experience_temperature": 22.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T14:30:07.873791+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 79.7, + "water_total": 7235.0, + "average_temperature": 28.9, + "experience_temperature": 22.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T14:40:07.812347+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 80.9, + "water_total": 7278.0, + "average_temperature": 28.5, + "experience_temperature": 22.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T14:50:07.012090+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 82.1, + "water_total": 7317.0, + "average_temperature": 28.3667, + "experience_temperature": 22.7367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T15:10:06.719356+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 83.0, + "water_total": 7417.0, + "average_temperature": 28.6333, + "experience_temperature": 23.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T15:20:08.600744+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 83.0, + "water_total": 7417.0, + "average_temperature": 28.6333, + "experience_temperature": 23.5333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T15:30:08.432518+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 79.5, + "water_total": 7519.0, + "average_temperature": 29.6667, + "experience_temperature": 22.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T15:40:06.567329+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.7, + "humidity": 79.5, + "water_total": 7567.0, + "average_temperature": 29.9333, + "experience_temperature": 22.3833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T15:50:07.025758+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 81.3, + "water_total": 7627.0, + "average_temperature": 29.8, + "experience_temperature": 22.96, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T16:10:08.600460+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 80.9, + "water_total": 7760.0, + "average_temperature": 29.7667, + "experience_temperature": 23.1967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T16:20:08.115147+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.7, + "humidity": 80.6, + "water_total": 7813.0, + "average_temperature": 29.8333, + "experience_temperature": 22.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T16:30:09.740122+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.9, + "humidity": 80.6, + "water_total": 7866.0, + "average_temperature": 29.9, + "experience_temperature": 21.87, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T16:40:07.887444+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.7, + "humidity": 81.5, + "water_total": 7922.0, + "average_temperature": 29.7333, + "experience_temperature": 22.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T16:50:06.916403+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 82.1, + "water_total": 8000.0, + "average_temperature": 29.5, + "experience_temperature": 23.87, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T17:10:06.942820+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 82.4, + "water_total": 66.0, + "average_temperature": 29.2, + "experience_temperature": 23.98, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T17:20:06.699177+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 83.4, + "water_total": 120.0, + "average_temperature": 29.1, + "experience_temperature": 23.38, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T17:30:06.782928+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 82.6, + "water_total": 155.0, + "average_temperature": 29.0333, + "experience_temperature": 23.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T17:40:07.558078+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.6, + "humidity": 83.1, + "water_total": 188.0, + "average_temperature": 28.8333, + "experience_temperature": 22.3533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T17:50:06.672835+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 82.1, + "water_total": 223.0, + "average_temperature": 28.7, + "experience_temperature": 23.42, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:00:06.726388+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 83.6, + "water_total": 227.0, + "average_temperature": 28.8, + "experience_temperature": 22.77, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:10:07.605424+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 84.6, + "water_total": 227.0, + "average_temperature": 28.5667, + "experience_temperature": 23.0867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:20:07.582986+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 86.4, + "water_total": 227.0, + "average_temperature": 28.0667, + "experience_temperature": 22.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:30:10.444575+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.1, + "humidity": 86.5, + "water_total": 227.0, + "average_temperature": 27.9, + "experience_temperature": 23.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:40:06.712400+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 87.4, + "water_total": 233.0, + "average_temperature": 28.1, + "experience_temperature": 22.83, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T18:50:07.298434+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 85.7, + "water_total": 324.0, + "average_temperature": 28.3, + "experience_temperature": 23.74, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:00:07.041923+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 89.9, + "water_total": 404.0, + "average_temperature": 28.1, + "experience_temperature": 24.38, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:10:07.111130+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.1, + "humidity": 89.1, + "water_total": 458.0, + "average_temperature": 28.0, + "experience_temperature": 24.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:20:07.151450+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.1, + "humidity": 87.6, + "water_total": 502.0, + "average_temperature": 27.9667, + "experience_temperature": 24.1367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:30:06.900754+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.1, + "humidity": 87.8, + "water_total": 554.0, + "average_temperature": 27.8667, + "experience_temperature": 24.0767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:40:06.464947+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.4, + "humidity": 86.7, + "water_total": 602.0, + "average_temperature": 28.0, + "experience_temperature": 22.94, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T19:50:07.818093+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 86.1, + "water_total": 648.0, + "average_temperature": 28.0667, + "experience_temperature": 23.5867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:00:07.114166+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 87.0, + "water_total": 693.0, + "average_temperature": 27.8, + "experience_temperature": 22.45, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:10:09.137372+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 87.3, + "water_total": 733.0, + "average_temperature": 28.0667, + "experience_temperature": 22.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:20:09.024132+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 85.1, + "water_total": 774.0, + "average_temperature": 28.1333, + "experience_temperature": 23.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:30:07.097524+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.3, + "humidity": 85.1, + "water_total": 774.0, + "average_temperature": 28.1333, + "experience_temperature": 23.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:40:07.214187+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.5, + "humidity": 85.8, + "water_total": 837.0, + "average_temperature": 27.9333, + "experience_temperature": 22.3433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T20:50:07.664392+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 85.9, + "water_total": 870.0, + "average_temperature": 27.7, + "experience_temperature": 24.93, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:00:06.707143+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 87.5, + "water_total": 905.0, + "average_temperature": 27.6333, + "experience_temperature": 24.4833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:10:07.837729+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 88.6, + "water_total": 948.0, + "average_temperature": 27.6333, + "experience_temperature": 25.0533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:20:06.734112+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.2, + "humidity": 88.7, + "water_total": 988.0, + "average_temperature": 27.8, + "experience_temperature": 23.84, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:30:05.800967+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.2, + "water_total": 1027.0, + "average_temperature": 27.4667, + "experience_temperature": 24.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:40:05.810131+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 88.5, + "water_total": 1073.0, + "average_temperature": 27.5333, + "experience_temperature": 24.9333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T21:50:06.373478+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 87.4, + "water_total": 1108.0, + "average_temperature": 27.4333, + "experience_temperature": 24.6133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:00:09.711957+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 86.9, + "water_total": 1155.0, + "average_temperature": 27.4333, + "experience_temperature": 24.5133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:10:08.013421+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.5, + "humidity": 87.3, + "water_total": 1214.0, + "average_temperature": 27.3333, + "experience_temperature": 25.5433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:20:05.747335+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 87.9, + "water_total": 1258.0, + "average_temperature": 27.1667, + "experience_temperature": 24.0967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:30:05.694445+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.8, + "humidity": 88.0, + "water_total": 1303.0, + "average_temperature": 26.9, + "experience_temperature": 24.2, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:40:05.773807+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 1333.0, + "average_temperature": 26.7333, + "experience_temperature": 24.4233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T22:50:06.059502+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 1333.0, + "average_temperature": 26.7333, + "experience_temperature": 24.4233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:00:05.464478+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 2.0, + "humidity": 88.7, + "water_total": 1360.0, + "average_temperature": 26.7333, + "experience_temperature": 23.4733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:10:07.445380+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 1365.0, + "average_temperature": 26.6667, + "experience_temperature": 23.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:20:05.827207+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 1365.0, + "average_temperature": 26.7667, + "experience_temperature": 23.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:30:06.068538+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.5, + "water_total": 1365.0, + "average_temperature": 26.7, + "experience_temperature": 23.75, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:40:06.287470+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 88.9, + "water_total": 1366.0, + "average_temperature": 26.7333, + "experience_temperature": 23.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-23T23:50:07.085835+07:00", + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.0, + "water_total": 1370.0, + "average_temperature": 26.6333, + "experience_temperature": 23.7833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:00:05.844258+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 1370.0, + "average_temperature": 26.6, + "experience_temperature": 23.67, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:10:06.155433+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 1377.0, + "average_temperature": 27.2333, + "experience_temperature": 24.4033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:20:06.200713+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 87.1, + "water_total": 1470.0, + "average_temperature": 27.2333, + "experience_temperature": 24.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:30:05.984454+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 88.0, + "water_total": 1548.0, + "average_temperature": 26.9333, + "experience_temperature": 23.8833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:40:05.600261+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 88.5, + "water_total": 1586.0, + "average_temperature": 26.7667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T00:50:06.526384+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.0, + "humidity": 90.9, + "water_total": 1618.0, + "average_temperature": 26.9, + "experience_temperature": 24.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:00:06.637942+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 92.1, + "water_total": 1646.0, + "average_temperature": 26.4667, + "experience_temperature": 24.2367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:10:05.728350+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 89.9, + "water_total": 1680.0, + "average_temperature": 26.4667, + "experience_temperature": 23.7967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:20:05.417587+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 1713.0, + "average_temperature": 26.0333, + "experience_temperature": 23.2833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:30:06.534873+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.9, + "water_total": 1736.0, + "average_temperature": 25.8667, + "experience_temperature": 24.0967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:40:06.113446+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 89.9, + "water_total": 1749.0, + "average_temperature": 26.0, + "experience_temperature": 24.03, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T01:50:05.806996+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.2, + "water_total": 1749.0, + "average_temperature": 25.9667, + "experience_temperature": 23.3567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:00:06.524790+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.2, + "water_total": 1749.0, + "average_temperature": 25.9667, + "experience_temperature": 23.3567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:10:05.308655+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.9, + "water_total": 1754.0, + "average_temperature": 26.0667, + "experience_temperature": 23.5967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:20:05.981375+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 88.3, + "water_total": 1813.0, + "average_temperature": 26.6, + "experience_temperature": 23.61, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:30:06.052307+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.8, + "humidity": 90.9, + "water_total": 1895.0, + "average_temperature": 26.2, + "experience_temperature": 24.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:40:05.891244+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 94.7, + "water_total": 1930.0, + "average_temperature": 25.7667, + "experience_temperature": 24.0567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T02:50:06.686683+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.4, + "humidity": 93.5, + "water_total": 1951.0, + "average_temperature": 25.5667, + "experience_temperature": 25.3667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:00:05.803187+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 93.0, + "water_total": 1978.0, + "average_temperature": 25.5667, + "experience_temperature": 24.5667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:10:05.241331+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.6, + "water_total": 1999.0, + "average_temperature": 25.6333, + "experience_temperature": 23.8033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:20:05.396103+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 91.6, + "water_total": 2014.0, + "average_temperature": 25.5333, + "experience_temperature": 24.2533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:30:06.190429+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.8, + "water_total": 2040.0, + "average_temperature": 25.5667, + "experience_temperature": 23.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:40:05.749301+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.8, + "humidity": 91.0, + "water_total": 2064.0, + "average_temperature": 25.7333, + "experience_temperature": 23.6333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T03:50:05.311665+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.3, + "water_total": 2088.0, + "average_temperature": 25.7, + "experience_temperature": 23.11, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:00:05.570449+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.5, + "water_total": 2103.0, + "average_temperature": 25.6667, + "experience_temperature": 23.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:10:06.099101+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.4, + "humidity": 89.8, + "water_total": 2118.0, + "average_temperature": 25.5667, + "experience_temperature": 24.6267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:20:05.957176+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.4, + "humidity": 89.1, + "water_total": 2144.0, + "average_temperature": 25.6333, + "experience_temperature": 24.5533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:30:06.038735+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 89.5, + "water_total": 2170.0, + "average_temperature": 25.8, + "experience_temperature": 24.1, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:40:06.060885+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.2, + "humidity": 90.8, + "water_total": 2191.0, + "average_temperature": 25.6, + "experience_temperature": 25.56, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T04:50:05.482256+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.8, + "humidity": 91.9, + "water_total": 2217.0, + "average_temperature": 25.5667, + "experience_temperature": 23.6467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:00:06.198044+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 90.8, + "water_total": 2237.0, + "average_temperature": 25.4667, + "experience_temperature": 24.0267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:10:06.507779+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.8, + "water_total": 2257.0, + "average_temperature": 25.5, + "experience_temperature": 23.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:20:06.398719+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.5, + "water_total": 2279.0, + "average_temperature": 25.5667, + "experience_temperature": 23.7167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:30:07.004936+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 90.1, + "water_total": 2301.0, + "average_temperature": 25.4667, + "experience_temperature": 23.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:40:06.406197+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.4, + "humidity": 90.4, + "water_total": 2327.0, + "average_temperature": 25.3667, + "experience_temperature": 24.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T05:50:06.896384+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 92.2, + "water_total": 2348.0, + "average_temperature": 25.5, + "experience_temperature": 24.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:00:06.163682+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 92.2, + "water_total": 2348.0, + "average_temperature": 25.5, + "experience_temperature": 24.34, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:10:05.683593+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 92.7, + "water_total": 2402.0, + "average_temperature": 25.3667, + "experience_temperature": 23.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:20:05.732037+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.7, + "humidity": 91.7, + "water_total": 2422.0, + "average_temperature": 25.3667, + "experience_temperature": 23.7567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:30:06.292982+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.6, + "humidity": 91.2, + "water_total": 2432.0, + "average_temperature": 25.4333, + "experience_temperature": 24.0733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:40:07.025544+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.5, + "humidity": 91.6, + "water_total": 2442.0, + "average_temperature": 25.2333, + "experience_temperature": 24.3033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T06:50:06.174736+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 91.5, + "water_total": 2446.0, + "average_temperature": 25.5, + "experience_temperature": 21.05, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:00:05.726784+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.1, + "humidity": 91.0, + "water_total": 2473.0, + "average_temperature": 25.5667, + "experience_temperature": 22.4167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:10:06.666286+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.8, + "humidity": 91.9, + "water_total": 2494.0, + "average_temperature": 25.4333, + "experience_temperature": 23.5133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:20:06.111137+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 92.3, + "water_total": 2504.0, + "average_temperature": 25.5667, + "experience_temperature": 21.6267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:30:06.312445+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 91.5, + "water_total": 2513.0, + "average_temperature": 25.8333, + "experience_temperature": 21.0333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:40:06.065919+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.1, + "humidity": 91.2, + "water_total": 2529.0, + "average_temperature": 26.0, + "experience_temperature": 22.89, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T07:50:07.617745+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.9, + "water_total": 2550.0, + "average_temperature": 26.3, + "experience_temperature": 23.83, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:00:05.725991+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.9, + "water_total": 2550.0, + "average_temperature": 26.3, + "experience_temperature": 23.83, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:10:05.207057+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 88.7, + "water_total": 2565.0, + "average_temperature": 26.5667, + "experience_temperature": 19.4567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:20:06.873024+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 85.4, + "water_total": 2580.0, + "average_temperature": 27.5333, + "experience_temperature": 21.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:30:06.072641+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 4.1, + "humidity": 82.3, + "water_total": 2629.0, + "average_temperature": 27.9667, + "experience_temperature": 16.0767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:40:06.666335+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 82.1, + "water_total": 2638.0, + "average_temperature": 28.3667, + "experience_temperature": 22.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T08:50:07.096829+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 81.0, + "water_total": 2653.0, + "average_temperature": 28.7, + "experience_temperature": 20.05, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:00:06.031601+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 79.7, + "water_total": 2663.0, + "average_temperature": 29.5333, + "experience_temperature": 23.0733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:10:05.942804+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.7, + "humidity": 78.2, + "water_total": 2684.0, + "average_temperature": 29.6, + "experience_temperature": 21.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:20:07.576984+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 73.5, + "water_total": 2699.0, + "average_temperature": 29.8333, + "experience_temperature": 21.4333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:30:07.563134+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 5.1, + "humidity": 71.6, + "water_total": 2709.0, + "average_temperature": 30.0667, + "experience_temperature": 12.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:40:06.857680+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 5.7, + "humidity": 71.7, + "water_total": 2719.0, + "average_temperature": 30.1667, + "experience_temperature": 10.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T09:50:07.291333+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 72.3, + "water_total": 2734.0, + "average_temperature": 30.2333, + "experience_temperature": 20.1933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:00:07.055500+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 72.3, + "water_total": 2734.0, + "average_temperature": 30.2333, + "experience_temperature": 20.1933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:10:06.741673+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 5.6, + "humidity": 71.5, + "water_total": 2753.0, + "average_temperature": 30.5667, + "experience_temperature": 11.2667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:20:06.932366+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 70.9, + "water_total": 2763.0, + "average_temperature": 30.4333, + "experience_temperature": 19.4133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:30:06.566996+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 70.9, + "water_total": 2778.0, + "average_temperature": 30.6667, + "experience_temperature": 21.0467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:40:06.059571+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 70.5, + "water_total": 2783.0, + "average_temperature": 30.7667, + "experience_temperature": 21.0667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T10:50:08.944427+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 69.6, + "water_total": 2792.0, + "average_temperature": 31.0667, + "experience_temperature": 21.1867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:00:06.574789+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 69.5, + "water_total": 2802.0, + "average_temperature": 31.0667, + "experience_temperature": 20.4667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:10:07.227604+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 69.2, + "water_total": 2807.0, + "average_temperature": 30.8333, + "experience_temperature": 20.5233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:20:05.994619+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 69.2, + "water_total": 2807.0, + "average_temperature": 30.8333, + "experience_temperature": 20.5233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:30:07.315387+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 70.9, + "water_total": 2827.0, + "average_temperature": 31.2333, + "experience_temperature": 22.3133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:40:08.250367+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 68.4, + "water_total": 2838.0, + "average_temperature": 31.1333, + "experience_temperature": 20.3133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T11:50:06.929882+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 68.4, + "water_total": 2838.0, + "average_temperature": 31.1333, + "experience_temperature": 20.3133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:00:06.458050+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 69.2, + "water_total": 2857.0, + "average_temperature": 31.0333, + "experience_temperature": 19.6733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:10:07.448767+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 67.0, + "water_total": 2903.0, + "average_temperature": 31.4333, + "experience_temperature": 20.3333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:20:07.371590+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 69.7, + "water_total": 2919.0, + "average_temperature": 31.3, + "experience_temperature": 20.04, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:30:06.507939+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 68.5, + "water_total": 2946.0, + "average_temperature": 31.5667, + "experience_temperature": 21.4667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:40:06.496726+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 67.3, + "water_total": 2968.0, + "average_temperature": 31.2, + "experience_temperature": 19.46, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T12:50:07.268239+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 68.5, + "water_total": 2989.0, + "average_temperature": 31.2333, + "experience_temperature": 19.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:00:07.060182+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 68.2, + "water_total": 3006.0, + "average_temperature": 31.0333, + "experience_temperature": 20.8733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:10:07.806777+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.7, + "humidity": 67.5, + "water_total": 3025.0, + "average_temperature": 31.4667, + "experience_temperature": 21.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:20:06.663958+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 66.1, + "water_total": 3038.0, + "average_temperature": 31.4, + "experience_temperature": 19.42, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:30:07.451724+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 70.0, + "water_total": 3058.0, + "average_temperature": 31.9333, + "experience_temperature": 20.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:40:06.876351+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 69.8, + "water_total": 3077.0, + "average_temperature": 31.5333, + "experience_temperature": 20.9933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T13:50:07.783849+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 71.9, + "water_total": 3093.0, + "average_temperature": 31.2, + "experience_temperature": 20.73, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T14:10:07.761617+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 70.4, + "water_total": 3113.0, + "average_temperature": 31.3333, + "experience_temperature": 20.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T14:20:07.190743+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 70.1, + "water_total": 3124.0, + "average_temperature": 31.6333, + "experience_temperature": 21.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T14:30:06.716761+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 73.6, + "water_total": 3134.0, + "average_temperature": 30.8, + "experience_temperature": 21.02, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T14:40:07.642366+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 75.1, + "water_total": 3144.0, + "average_temperature": 30.7667, + "experience_temperature": 21.6367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T14:50:06.050470+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.2, + "humidity": 73.6, + "water_total": 3154.0, + "average_temperature": 31.3, + "experience_temperature": 20.82, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T15:10:17.322956+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 73.6, + "water_total": 3180.0, + "average_temperature": 30.7667, + "experience_temperature": 20.9867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T15:20:05.933524+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 75.3, + "water_total": 3188.0, + "average_temperature": 30.8333, + "experience_temperature": 21.7433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T15:30:05.392022+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 73.1, + "water_total": 3200.0, + "average_temperature": 31.0333, + "experience_temperature": 21.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T15:40:05.905990+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 73.1, + "water_total": 3200.0, + "average_temperature": 31.0333, + "experience_temperature": 21.5033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T15:50:05.882765+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 75.4, + "water_total": 3220.0, + "average_temperature": 30.7, + "experience_temperature": 21.28, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T16:10:06.772781+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 77.7, + "water_total": 3240.0, + "average_temperature": 30.3667, + "experience_temperature": 22.1067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T16:20:06.526665+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.7, + "humidity": 77.9, + "water_total": 3245.0, + "average_temperature": 30.5, + "experience_temperature": 22.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T16:30:06.041449+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 77.8, + "water_total": 3255.0, + "average_temperature": 30.3, + "experience_temperature": 22.76, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T16:40:06.254362+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.8, + "humidity": 78.0, + "water_total": 3271.0, + "average_temperature": 30.3333, + "experience_temperature": 22.1333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T16:50:06.136336+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.7, + "humidity": 77.1, + "water_total": 3304.0, + "average_temperature": 30.4667, + "experience_temperature": 22.4367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T17:10:05.737812+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 79.5, + "water_total": 31.0, + "average_temperature": 29.4667, + "experience_temperature": 22.6167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T17:20:07.288417+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 79.6, + "water_total": 67.0, + "average_temperature": 29.4667, + "experience_temperature": 22.2867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T17:30:08.527088+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 78.1, + "water_total": 98.0, + "average_temperature": 29.7, + "experience_temperature": 20.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T17:40:06.032625+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.1, + "humidity": 78.1, + "water_total": 98.0, + "average_temperature": 29.7, + "experience_temperature": 20.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T17:50:07.411836+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 3.0, + "humidity": 75.4, + "water_total": 146.0, + "average_temperature": 29.9, + "experience_temperature": 20.48, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:00:06.560912+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.9, + "humidity": 80.3, + "water_total": 146.0, + "average_temperature": 29.2667, + "experience_temperature": 21.1767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:10:07.017179+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 81.8, + "water_total": 146.0, + "average_temperature": 28.8333, + "experience_temperature": 22.4433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:20:05.908515+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 82.4, + "water_total": 150.0, + "average_temperature": 28.7, + "experience_temperature": 22.43, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:30:05.950705+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.7, + "humidity": 82.4, + "water_total": 150.0, + "average_temperature": 28.7333, + "experience_temperature": 21.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:40:06.878600+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 82.5, + "water_total": 150.0, + "average_temperature": 28.7, + "experience_temperature": 22.8, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T18:50:06.256956+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.6, + "humidity": 83.3, + "water_total": 208.0, + "average_temperature": 28.6, + "experience_temperature": 22.16, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:00:05.695602+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 82.9, + "water_total": 254.0, + "average_temperature": 28.4667, + "experience_temperature": 22.6467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:10:06.413335+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 83.3, + "water_total": 287.0, + "average_temperature": 28.3333, + "experience_temperature": 22.9433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:20:05.439367+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 83.2, + "water_total": 309.0, + "average_temperature": 28.3, + "experience_temperature": 22.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:30:06.035433+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 83.3, + "water_total": 336.0, + "average_temperature": 28.2333, + "experience_temperature": 24.2433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:40:09.877134+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.2, + "humidity": 84.0, + "water_total": 363.0, + "average_temperature": 28.1, + "experience_temperature": 23.2, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T19:50:05.611967+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 84.5, + "water_total": 385.0, + "average_temperature": 27.9667, + "experience_temperature": 22.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:00:06.754234+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 84.5, + "water_total": 385.0, + "average_temperature": 27.9667, + "experience_temperature": 22.8167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:10:06.231375+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.5, + "humidity": 84.7, + "water_total": 427.0, + "average_temperature": 27.9, + "experience_temperature": 22.09, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:20:05.835584+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 85.4, + "water_total": 448.0, + "average_temperature": 27.8, + "experience_temperature": 24.23, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:30:06.713484+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 85.4, + "water_total": 470.0, + "average_temperature": 27.7667, + "experience_temperature": 22.7967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:40:08.528954+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.2, + "humidity": 86.0, + "water_total": 485.0, + "average_temperature": 27.6667, + "experience_temperature": 23.1667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T20:50:06.706528+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 85.9, + "water_total": 506.0, + "average_temperature": 27.6333, + "experience_temperature": 22.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:00:05.907365+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 86.2, + "water_total": 522.0, + "average_temperature": 27.5333, + "experience_temperature": 22.3733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:10:05.821992+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 85.8, + "water_total": 542.0, + "average_temperature": 27.6667, + "experience_temperature": 22.7767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:20:10.165356+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.2, + "humidity": 86.0, + "water_total": 564.0, + "average_temperature": 27.6, + "experience_temperature": 23.1, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:30:06.154663+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.4, + "humidity": 87.4, + "water_total": 591.0, + "average_temperature": 27.4667, + "experience_temperature": 22.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:40:08.633758+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.8, + "humidity": 87.2, + "water_total": 620.0, + "average_temperature": 27.4333, + "experience_temperature": 24.5733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T21:50:06.235135+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 658.0, + "average_temperature": 27.4, + "experience_temperature": 24.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:00:06.579125+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.2, + "humidity": 87.0, + "water_total": 681.0, + "average_temperature": 27.3, + "experience_temperature": 23.0, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:10:05.874512+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 87.6, + "water_total": 702.0, + "average_temperature": 27.2, + "experience_temperature": 24.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:20:06.245905+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 87.4, + "water_total": 723.0, + "average_temperature": 27.2667, + "experience_temperature": 24.0967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:30:06.211465+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.1, + "humidity": 87.5, + "water_total": 745.0, + "average_temperature": 27.0333, + "experience_temperature": 23.1833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:40:05.768407+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 760.0, + "average_temperature": 26.9, + "experience_temperature": 23.97, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T22:50:07.260632+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 781.0, + "average_temperature": 26.9333, + "experience_temperature": 24.1033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:00:06.506050+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.0, + "humidity": 89.4, + "water_total": 786.0, + "average_temperature": 26.7667, + "experience_temperature": 23.6467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:10:06.843597+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 786.0, + "average_temperature": 26.6, + "experience_temperature": 23.97, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:20:06.777400+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.3, + "humidity": 90.6, + "water_total": 786.0, + "average_temperature": 26.6333, + "experience_temperature": 22.7033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:30:06.114795+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.0, + "humidity": 90.9, + "water_total": 786.0, + "average_temperature": 26.7667, + "experience_temperature": 23.9467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:40:06.363745+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 2.0, + "humidity": 90.5, + "water_total": 786.0, + "average_temperature": 26.7333, + "experience_temperature": 23.8333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-24T23:50:06.198864+07:00", + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.5, + "water_total": 786.0, + "average_temperature": 26.7, + "experience_temperature": 24.15, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:00:05.921956+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 90.6, + "water_total": 791.0, + "average_temperature": 26.6, + "experience_temperature": 23.72, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:10:06.661207+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 90.4, + "water_total": 791.0, + "average_temperature": 26.7667, + "experience_temperature": 24.5467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:20:06.192919+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 89.9, + "water_total": 862.0, + "average_temperature": 26.7333, + "experience_temperature": 23.7133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:30:05.922282+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 89.4, + "water_total": 923.0, + "average_temperature": 26.6333, + "experience_temperature": 23.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:40:07.726758+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 90.5, + "water_total": 961.0, + "average_temperature": 26.4667, + "experience_temperature": 23.9167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T00:50:05.512426+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 986.0, + "average_temperature": 26.3333, + "experience_temperature": 23.7033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:00:05.890038+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 90.7, + "water_total": 1002.0, + "average_temperature": 26.3, + "experience_temperature": 23.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:10:06.434136+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 89.9, + "water_total": 1028.0, + "average_temperature": 26.3667, + "experience_temperature": 24.3967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:20:05.685701+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 90.8, + "water_total": 1050.0, + "average_temperature": 26.3333, + "experience_temperature": 23.4933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:30:06.321063+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 90.6, + "water_total": 1071.0, + "average_temperature": 26.2667, + "experience_temperature": 23.3867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:40:06.754360+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 90.8, + "water_total": 1091.0, + "average_temperature": 26.3667, + "experience_temperature": 24.5767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T01:50:06.465928+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.2, + "humidity": 91.0, + "water_total": 1091.0, + "average_temperature": 26.3, + "experience_temperature": 22.8, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:00:06.499521+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.3, + "water_total": 1091.0, + "average_temperature": 26.2667, + "experience_temperature": 23.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:10:06.437602+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 91.4, + "water_total": 1091.0, + "average_temperature": 26.4, + "experience_temperature": 23.33, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:20:06.115374+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 90.7, + "water_total": 1129.0, + "average_temperature": 26.6, + "experience_temperature": 24.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:30:06.584097+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 89.5, + "water_total": 1180.0, + "average_temperature": 26.6333, + "experience_temperature": 24.5833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:40:07.940721+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 90.4, + "water_total": 1209.0, + "average_temperature": 26.4, + "experience_temperature": 23.13, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T02:50:06.658944+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 91.6, + "water_total": 1229.0, + "average_temperature": 26.1333, + "experience_temperature": 23.4533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:00:07.299031+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 92.0, + "water_total": 1249.0, + "average_temperature": 26.1333, + "experience_temperature": 24.2333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:10:06.202082+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.6, + "water_total": 1264.0, + "average_temperature": 26.0333, + "experience_temperature": 23.7033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:20:06.100894+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.1, + "water_total": 1289.0, + "average_temperature": 26.0333, + "experience_temperature": 23.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:30:05.892005+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 91.8, + "water_total": 1310.0, + "average_temperature": 25.9667, + "experience_temperature": 23.3267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:40:05.510076+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 91.8, + "water_total": 1325.0, + "average_temperature": 26.0667, + "experience_temperature": 24.4767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T03:50:05.866714+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.0, + "water_total": 1337.0, + "average_temperature": 25.9, + "experience_temperature": 23.65, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:00:06.080245+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.0, + "water_total": 1337.0, + "average_temperature": 25.9, + "experience_temperature": 23.65, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:10:06.475311+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.9, + "water_total": 1369.0, + "average_temperature": 25.8333, + "experience_temperature": 23.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:20:08.185758+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 92.2, + "water_total": 1369.0, + "average_temperature": 25.8333, + "experience_temperature": 23.9733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:30:06.741262+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.9, + "water_total": 1369.0, + "average_temperature": 25.7, + "experience_temperature": 23.63, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:40:06.488796+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 92.8, + "water_total": 1369.0, + "average_temperature": 25.7, + "experience_temperature": 23.26, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T04:50:07.075482+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 92.6, + "water_total": 1369.0, + "average_temperature": 25.7, + "experience_temperature": 23.22, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:00:07.147755+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.9, + "water_total": 1369.0, + "average_temperature": 25.6333, + "experience_temperature": 23.5633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:10:07.271263+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 92.8, + "water_total": 1369.0, + "average_temperature": 25.5667, + "experience_temperature": 23.8267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:20:07.548910+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.2, + "water_total": 1398.0, + "average_temperature": 25.7667, + "experience_temperature": 23.5567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:30:06.326307+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 91.5, + "water_total": 1453.0, + "average_temperature": 25.7333, + "experience_temperature": 24.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:40:07.059450+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.0, + "water_total": 1485.0, + "average_temperature": 25.5667, + "experience_temperature": 23.1167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T05:50:06.362703+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 92.1, + "water_total": 1505.0, + "average_temperature": 25.4333, + "experience_temperature": 22.8533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:00:07.054895+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 92.6, + "water_total": 1518.0, + "average_temperature": 25.4333, + "experience_temperature": 23.6533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:10:06.497960+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 92.9, + "water_total": 1534.0, + "average_temperature": 25.3, + "experience_temperature": 22.88, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:20:07.089788+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 93.1, + "water_total": 1549.0, + "average_temperature": 25.3667, + "experience_temperature": 23.6867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:30:07.050235+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 92.8, + "water_total": 1575.0, + "average_temperature": 25.5, + "experience_temperature": 22.71, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:40:06.613016+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.3, + "water_total": 1595.0, + "average_temperature": 25.4667, + "experience_temperature": 23.2767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T06:50:09.124376+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 92.5, + "water_total": 1610.0, + "average_temperature": 25.5333, + "experience_temperature": 24.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:00:07.113009+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 91.7, + "water_total": 1630.0, + "average_temperature": 25.7, + "experience_temperature": 23.74, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:10:06.862015+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 92.1, + "water_total": 1650.0, + "average_temperature": 25.8333, + "experience_temperature": 23.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:20:06.673629+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 92.4, + "water_total": 1671.0, + "average_temperature": 25.9, + "experience_temperature": 23.38, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:30:05.767936+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.9, + "water_total": 1691.0, + "average_temperature": 26.0333, + "experience_temperature": 23.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:40:05.917253+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 91.6, + "water_total": 1717.0, + "average_temperature": 26.2667, + "experience_temperature": 23.9367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T07:50:05.681382+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 90.1, + "water_total": 1743.0, + "average_temperature": 26.6, + "experience_temperature": 23.97, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:00:06.722058+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 89.1, + "water_total": 1759.0, + "average_temperature": 27.0, + "experience_temperature": 24.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:10:06.985332+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 1798.0, + "average_temperature": 27.1, + "experience_temperature": 23.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:20:19.216791+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 87.0, + "water_total": 1798.0, + "average_temperature": 27.1, + "experience_temperature": 23.85, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:30:06.529461+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 85.2, + "water_total": 1859.0, + "average_temperature": 27.9, + "experience_temperature": 22.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:40:05.688337+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 85.2, + "water_total": 1859.0, + "average_temperature": 27.9, + "experience_temperature": 22.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T08:50:07.278507+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 82.8, + "water_total": 1900.0, + "average_temperature": 28.2667, + "experience_temperature": 21.7267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:00:06.524769+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 83.0, + "water_total": 1933.0, + "average_temperature": 28.2333, + "experience_temperature": 22.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:10:05.882609+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 83.1, + "water_total": 1960.0, + "average_temperature": 28.0333, + "experience_temperature": 22.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:20:05.904410+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 83.1, + "water_total": 1960.0, + "average_temperature": 28.0333, + "experience_temperature": 22.6033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:30:06.889973+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 81.3, + "water_total": 2007.0, + "average_temperature": 28.3333, + "experience_temperature": 22.5433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:40:09.203761+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 80.7, + "water_total": 2041.0, + "average_temperature": 28.8, + "experience_temperature": 22.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T09:50:07.875563+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 79.4, + "water_total": 2071.0, + "average_temperature": 29.1667, + "experience_temperature": 22.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:00:07.146378+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 79.4, + "water_total": 2071.0, + "average_temperature": 29.1667, + "experience_temperature": 22.2967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:10:05.800844+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 77.9, + "water_total": 2110.0, + "average_temperature": 29.2667, + "experience_temperature": 21.7467, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:20:07.068905+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 75.7, + "water_total": 2171.0, + "average_temperature": 29.8, + "experience_temperature": 20.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:30:06.036180+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 75.7, + "water_total": 2171.0, + "average_temperature": 29.8, + "experience_temperature": 20.79, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:40:06.398278+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 73.7, + "water_total": 2224.0, + "average_temperature": 30.9, + "experience_temperature": 21.49, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T10:50:06.721213+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 73.7, + "water_total": 2253.0, + "average_temperature": 30.5333, + "experience_temperature": 21.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:00:11.854039+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 73.7, + "water_total": 2253.0, + "average_temperature": 30.5333, + "experience_temperature": 21.1233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:10:09.434335+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 3.0, + "humidity": 74.2, + "water_total": 2282.0, + "average_temperature": 30.6333, + "experience_temperature": 20.9733, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:20:06.038087+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 3.0, + "humidity": 75.0, + "water_total": 2327.0, + "average_temperature": 30.6, + "experience_temperature": 21.1, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:30:10.142596+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 73.2, + "water_total": 2349.0, + "average_temperature": 31.0333, + "experience_temperature": 21.5233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:40:07.772873+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 3.2, + "humidity": 73.4, + "water_total": 2372.0, + "average_temperature": 30.6, + "experience_temperature": 20.08, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T11:50:07.898960+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 75.0, + "water_total": 2394.0, + "average_temperature": 30.1333, + "experience_temperature": 22.0333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:00:07.722019+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 78.5, + "water_total": 2410.0, + "average_temperature": 29.2333, + "experience_temperature": 21.8333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:10:06.471671+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 85.6, + "water_total": 2416.0, + "average_temperature": 28.8, + "experience_temperature": 23.17, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:20:06.674202+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 83.7, + "water_total": 2435.0, + "average_temperature": 28.2, + "experience_temperature": 24.29, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:30:08.693599+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 83.4, + "water_total": 2456.0, + "average_temperature": 28.6667, + "experience_temperature": 22.5967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:40:07.532038+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 81.1, + "water_total": 2471.0, + "average_temperature": 28.9667, + "experience_temperature": 22.4367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T12:50:07.089543+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 79.8, + "water_total": 2487.0, + "average_temperature": 29.6, + "experience_temperature": 22.81, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:00:06.550338+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 78.2, + "water_total": 2503.0, + "average_temperature": 29.9, + "experience_temperature": 22.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:10:05.891028+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 78.2, + "water_total": 2503.0, + "average_temperature": 29.9, + "experience_temperature": 22.44, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:20:06.998880+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 79.0, + "water_total": 2546.0, + "average_temperature": 28.9333, + "experience_temperature": 21.9833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:30:06.845978+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 80.3, + "water_total": 2561.0, + "average_temperature": 28.6, + "experience_temperature": 20.51, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:40:06.906586+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 81.6, + "water_total": 2577.0, + "average_temperature": 28.5, + "experience_temperature": 22.07, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T13:50:06.163945+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.9, + "humidity": 81.2, + "water_total": 2597.0, + "average_temperature": 28.3667, + "experience_temperature": 20.4567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T14:10:06.637937+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 82.0, + "water_total": 2641.0, + "average_temperature": 28.4333, + "experience_temperature": 22.0833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T14:20:06.638571+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 83.3, + "water_total": 2661.0, + "average_temperature": 28.3, + "experience_temperature": 22.21, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T14:30:07.506311+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 84.0, + "water_total": 2671.0, + "average_temperature": 28.2, + "experience_temperature": 22.25, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T14:40:06.906324+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 84.0, + "water_total": 2671.0, + "average_temperature": 28.2, + "experience_temperature": 22.25, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T14:50:06.007681+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 83.8, + "water_total": 2719.0, + "average_temperature": 28.1333, + "experience_temperature": 22.1433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T15:10:06.359303+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 82.6, + "water_total": 2755.0, + "average_temperature": 27.8667, + "experience_temperature": 23.0367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T15:20:06.609138+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 78.8, + "water_total": 2771.0, + "average_temperature": 28.1667, + "experience_temperature": 22.5767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T15:30:07.390642+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 79.8, + "water_total": 2786.0, + "average_temperature": 28.5, + "experience_temperature": 23.46, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T15:40:05.972510+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 80.3, + "water_total": 2806.0, + "average_temperature": 28.5667, + "experience_temperature": 22.5767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T15:50:07.358161+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 81.5, + "water_total": 2816.0, + "average_temperature": 28.4667, + "experience_temperature": 22.0167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T16:10:07.316499+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.4, + "humidity": 83.1, + "water_total": 2865.0, + "average_temperature": 28.6, + "experience_temperature": 22.82, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T16:20:08.188965+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.4, + "humidity": 82.9, + "water_total": 2890.0, + "average_temperature": 28.8333, + "experience_temperature": 23.0133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T16:30:10.022165+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.4, + "humidity": 80.9, + "water_total": 2934.0, + "average_temperature": 29.0333, + "experience_temperature": 22.8133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T16:40:06.726746+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 3.0, + "humidity": 81.5, + "water_total": 2967.0, + "average_temperature": 28.9333, + "experience_temperature": 20.7333, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T16:50:07.402421+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.7, + "humidity": 81.7, + "water_total": 2989.0, + "average_temperature": 29.0667, + "experience_temperature": 21.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T17:10:06.409812+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.7, + "humidity": 82.9, + "water_total": 15.0, + "average_temperature": 28.7333, + "experience_temperature": 21.8633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T17:20:06.226007+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 83.1, + "water_total": 29.0, + "average_temperature": 28.6667, + "experience_temperature": 22.5367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T17:30:07.203201+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 84.8, + "water_total": 44.0, + "average_temperature": 28.6333, + "experience_temperature": 22.4933, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T17:40:06.317717+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 83.6, + "water_total": 54.0, + "average_temperature": 28.5667, + "experience_temperature": 22.1867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T17:50:06.326044+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.6, + "humidity": 82.2, + "water_total": 70.0, + "average_temperature": 28.4667, + "experience_temperature": 21.8067, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:00:06.697259+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.7, + "humidity": 82.7, + "water_total": 74.0, + "average_temperature": 28.2333, + "experience_temperature": 21.3233, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:10:05.879733+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 84.3, + "water_total": 74.0, + "average_temperature": 28.0667, + "experience_temperature": 22.8767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:20:07.742737+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 85.0, + "water_total": 74.0, + "average_temperature": 28.0333, + "experience_temperature": 22.9833, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:30:05.749280+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 85.8, + "water_total": 74.0, + "average_temperature": 27.8, + "experience_temperature": 22.21, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:40:05.875515+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 86.8, + "water_total": 74.0, + "average_temperature": 27.7333, + "experience_temperature": 22.3433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T18:50:07.473999+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.4, + "humidity": 87.0, + "water_total": 112.0, + "average_temperature": 27.9667, + "experience_temperature": 22.9667, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:00:06.312932+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.5, + "humidity": 87.1, + "water_total": 158.0, + "average_temperature": 27.7333, + "experience_temperature": 22.4033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:10:07.027127+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 87.6, + "water_total": 191.0, + "average_temperature": 27.5333, + "experience_temperature": 23.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:20:08.229988+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 88.1, + "water_total": 212.0, + "average_temperature": 27.2667, + "experience_temperature": 22.8367, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:30:06.019440+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.2, + "humidity": 88.5, + "water_total": 232.0, + "average_temperature": 27.3, + "experience_temperature": 23.3, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:40:06.374038+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.2, + "humidity": 88.3, + "water_total": 252.0, + "average_temperature": 27.3, + "experience_temperature": 23.26, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T19:50:05.799765+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 87.7, + "water_total": 273.0, + "average_temperature": 27.2667, + "experience_temperature": 23.4567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:00:07.488423+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 87.7, + "water_total": 273.0, + "average_temperature": 27.2667, + "experience_temperature": 23.4567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:10:06.246515+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.2, + "humidity": 88.6, + "water_total": 313.0, + "average_temperature": 27.1667, + "experience_temperature": 23.1867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:20:09.641735+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.4, + "humidity": 88.4, + "water_total": 335.0, + "average_temperature": 27.2, + "experience_temperature": 22.48, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:30:06.585652+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.1, + "water_total": 358.0, + "average_temperature": 27.0333, + "experience_temperature": 24.0033, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:40:06.350793+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.4, + "water_total": 378.0, + "average_temperature": 27.0333, + "experience_temperature": 24.0633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T20:50:05.863179+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.9, + "water_total": 403.0, + "average_temperature": 26.8, + "experience_temperature": 23.93, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T21:00:05.605182+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.9, + "water_total": 403.0, + "average_temperature": 26.8, + "experience_temperature": 23.93, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T21:10:06.522458+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 89.3, + "water_total": 438.0, + "average_temperature": 26.7333, + "experience_temperature": 23.2433, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T21:20:08.082803+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.7, + "water_total": 447.0, + "average_temperature": 26.8, + "experience_temperature": 23.89, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T21:30:06.050946+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 89.2, + "water_total": 461.0, + "average_temperature": 26.7667, + "experience_temperature": 23.9567, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T21:50:06.726665+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 89.4, + "water_total": 480.0, + "average_temperature": 26.5333, + "experience_temperature": 23.7633, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:00:06.644596+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.7, + "humidity": 89.1, + "water_total": 489.0, + "average_temperature": 26.8, + "experience_temperature": 24.67, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:10:07.176025+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 88.8, + "water_total": 499.0, + "average_temperature": 26.5667, + "experience_temperature": 23.6767, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:20:06.494090+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.8, + "humidity": 89.1, + "water_total": 508.0, + "average_temperature": 26.4667, + "experience_temperature": 23.9867, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:30:07.891114+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 86.8, + "water_total": 512.0, + "average_temperature": 26.4667, + "experience_temperature": 22.8267, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:40:06.529481+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 89.9, + "water_total": 517.0, + "average_temperature": 26.2333, + "experience_temperature": 23.2133, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T22:50:06.438199+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 89.9, + "water_total": 522.0, + "average_temperature": 26.2667, + "experience_temperature": 23.5967, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:00:06.361784+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 86.8, + "water_total": 526.0, + "average_temperature": 26.4, + "experience_temperature": 22.41, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:10:06.391574+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.0, + "humidity": 86.1, + "water_total": 531.0, + "average_temperature": 26.2333, + "experience_temperature": 22.4533, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:20:06.540182+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 1.9, + "humidity": 86.8, + "water_total": 535.0, + "average_temperature": 26.3, + "experience_temperature": 23.01, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:30:06.815345+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.1, + "humidity": 86.2, + "water_total": 540.0, + "average_temperature": 26.3, + "experience_temperature": 22.19, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:40:06.870589+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 87.0, + "water_total": 544.0, + "average_temperature": 26.1667, + "experience_temperature": 21.5167, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-25T23:50:06.312206+07:00", + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 86.6, + "water_total": 549.0, + "average_temperature": 26.2, + "experience_temperature": 21.47, + "chill_factor": 3.5 + }, + { + "timestamp": "2026-06-26T00:00:11.150519+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 86.5, + "water_total": 555.0, + "average_temperature": 26.0667, + "experience_temperature": 22.5095, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T00:10:07.289884+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 88.5, + "water_total": 555.0, + "average_temperature": 25.8333, + "experience_temperature": 23.019, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T00:20:06.575828+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 89.2, + "water_total": 560.0, + "average_temperature": 26.1, + "experience_temperature": 23.7686, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T00:30:06.132340+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 89.5, + "water_total": 560.0, + "average_temperature": 25.6333, + "experience_temperature": 23.019, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T00:40:08.147208+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.2, + "humidity": 92.1, + "water_total": 564.0, + "average_temperature": 25.5, + "experience_temperature": 18.9486, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T00:50:06.204664+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.3, + "humidity": 92.4, + "water_total": 564.0, + "average_temperature": 25.4, + "experience_temperature": 18.5657, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:00:07.550201+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.0, + "humidity": 93.0, + "water_total": 569.0, + "average_temperature": 25.3, + "experience_temperature": 19.6143, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:10:07.979267+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.3, + "water_total": 569.0, + "average_temperature": 25.1667, + "experience_temperature": 23.3124, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:20:06.448039+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.2, + "water_total": 574.0, + "average_temperature": 25.2, + "experience_temperature": 23.3257, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:30:08.086654+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 93.0, + "water_total": 578.0, + "average_temperature": 25.0667, + "experience_temperature": 23.4952, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:40:06.417452+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 92.8, + "water_total": 583.0, + "average_temperature": 25.0333, + "experience_temperature": 23.079, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T01:50:07.617606+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.7, + "humidity": 93.1, + "water_total": 588.0, + "average_temperature": 24.9667, + "experience_temperature": 23.7581, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:00:06.957143+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.1, + "water_total": 592.0, + "average_temperature": 24.9667, + "experience_temperature": 23.0724, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:10:06.422237+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.2, + "water_total": 597.0, + "average_temperature": 24.8, + "experience_temperature": 22.5829, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:20:06.513225+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.4, + "water_total": 601.0, + "average_temperature": 24.8, + "experience_temperature": 22.9657, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:30:06.628275+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.4, + "water_total": 606.0, + "average_temperature": 24.7, + "experience_temperature": 22.8657, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:40:06.458247+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.3, + "water_total": 611.0, + "average_temperature": 24.6667, + "experience_temperature": 22.8124, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T02:50:06.283403+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.4, + "water_total": 611.0, + "average_temperature": 24.6667, + "experience_temperature": 22.4895, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:00:06.672177+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.4, + "water_total": 611.0, + "average_temperature": 24.6667, + "experience_temperature": 22.4895, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:10:06.543927+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.4, + "water_total": 620.0, + "average_temperature": 24.6333, + "experience_temperature": 22.799, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:20:06.789753+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.5, + "water_total": 624.0, + "average_temperature": 24.5333, + "experience_temperature": 22.719, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:30:08.199878+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.5, + "water_total": 629.0, + "average_temperature": 24.5333, + "experience_temperature": 22.719, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:40:06.121479+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.1, + "water_total": 629.0, + "average_temperature": 24.5333, + "experience_temperature": 22.639, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T03:50:06.708444+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 93.1, + "water_total": 634.0, + "average_temperature": 24.4, + "experience_temperature": 23.5343, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:00:05.678742+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 92.9, + "water_total": 638.0, + "average_temperature": 24.3, + "experience_temperature": 23.3943, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:10:05.995975+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.7, + "humidity": 93.2, + "water_total": 643.0, + "average_temperature": 24.5333, + "experience_temperature": 23.3448, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:20:06.165722+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.5, + "humidity": 93.1, + "water_total": 643.0, + "average_temperature": 24.4667, + "experience_temperature": 23.9438, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:30:07.164828+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 93.1, + "water_total": 647.0, + "average_temperature": 24.5667, + "experience_temperature": 23.0152, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:40:06.098758+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 92.9, + "water_total": 647.0, + "average_temperature": 24.2333, + "experience_temperature": 23.3276, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T04:50:05.924244+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 92.9, + "water_total": 647.0, + "average_temperature": 24.2333, + "experience_temperature": 23.3276, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:00:05.810248+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 94.5, + "water_total": 652.0, + "average_temperature": 24.1333, + "experience_temperature": 22.519, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:10:05.699419+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 95.0, + "water_total": 652.0, + "average_temperature": 24.0333, + "experience_temperature": 23.5476, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:20:06.254254+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 95.2, + "water_total": 657.0, + "average_temperature": 24.1333, + "experience_temperature": 23.6876, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:30:06.287555+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 94.5, + "water_total": 661.0, + "average_temperature": 24.1333, + "experience_temperature": 23.5476, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:40:05.609780+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.5, + "humidity": 93.6, + "water_total": 666.0, + "average_temperature": 24.0667, + "experience_temperature": 23.6438, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T05:50:05.825002+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.2, + "humidity": 94.1, + "water_total": 671.0, + "average_temperature": 24.1667, + "experience_temperature": 24.8724, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:00:06.470839+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.2, + "humidity": 94.1, + "water_total": 671.0, + "average_temperature": 24.1667, + "experience_temperature": 24.8724, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:10:06.974801+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 92.9, + "water_total": 680.0, + "average_temperature": 23.9667, + "experience_temperature": 23.061, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:20:06.732933+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.3, + "humidity": 93.7, + "water_total": 684.0, + "average_temperature": 24.0667, + "experience_temperature": 24.3495, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:30:06.542339+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 94.2, + "water_total": 694.0, + "average_temperature": 24.1, + "experience_temperature": 23.4543, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:40:06.618278+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.5, + "humidity": 94.6, + "water_total": 698.0, + "average_temperature": 24.3, + "experience_temperature": 24.0771, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T06:50:07.477822+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.5, + "humidity": 94.3, + "water_total": 703.0, + "average_temperature": 24.3, + "experience_temperature": 24.0171, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:00:06.049245+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.4, + "humidity": 94.1, + "water_total": 707.0, + "average_temperature": 24.4, + "experience_temperature": 24.42, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:10:06.308186+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.9, + "water_total": 712.0, + "average_temperature": 24.5333, + "experience_temperature": 22.4562, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:20:06.453259+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 93.9, + "water_total": 717.0, + "average_temperature": 24.7, + "experience_temperature": 23.9943, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:30:06.348593+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.6, + "water_total": 721.0, + "average_temperature": 24.7667, + "experience_temperature": 22.9724, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:40:06.818928+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.4, + "water_total": 726.0, + "average_temperature": 24.9333, + "experience_temperature": 23.099, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T07:50:06.298907+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 93.2, + "water_total": 731.0, + "average_temperature": 25.0667, + "experience_temperature": 23.1924, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:00:06.852209+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 93.6, + "water_total": 735.0, + "average_temperature": 25.1667, + "experience_temperature": 23.7152, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:10:06.931855+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 93.6, + "water_total": 735.0, + "average_temperature": 25.1667, + "experience_temperature": 23.7152, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:20:06.606953+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.6, + "water_total": 777.0, + "average_temperature": 25.8667, + "experience_temperature": 23.7295, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:30:07.614197+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 93.6, + "water_total": 777.0, + "average_temperature": 25.8667, + "experience_temperature": 23.7295, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:40:06.544226+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 88.8, + "water_total": 807.0, + "average_temperature": 27.0, + "experience_temperature": 23.9029, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T08:50:06.436895+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 87.5, + "water_total": 817.0, + "average_temperature": 27.3667, + "experience_temperature": 22.6381, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:00:07.514178+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 87.5, + "water_total": 817.0, + "average_temperature": 27.3667, + "experience_temperature": 22.6381, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:10:06.423658+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.2, + "humidity": 85.3, + "water_total": 837.0, + "average_temperature": 27.8333, + "experience_temperature": 23.3505, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:20:06.195344+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 81.2, + "water_total": 878.0, + "average_temperature": 28.6333, + "experience_temperature": 22.6448, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:30:06.449726+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 81.2, + "water_total": 888.0, + "average_temperature": 28.8667, + "experience_temperature": 22.5352, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:40:06.241484+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.6, + "humidity": 79.9, + "water_total": 897.0, + "average_temperature": 28.8667, + "experience_temperature": 21.9324, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T09:50:06.749411+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 81.1, + "water_total": 912.0, + "average_temperature": 29.0333, + "experience_temperature": 23.3676, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:00:06.654529+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 79.6, + "water_total": 933.0, + "average_temperature": 29.3333, + "experience_temperature": 23.0248, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:10:10.585003+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 78.6, + "water_total": 948.0, + "average_temperature": 28.9333, + "experience_temperature": 22.4248, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:20:06.160858+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 78.5, + "water_total": 957.0, + "average_temperature": 29.6667, + "experience_temperature": 22.7952, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:30:06.948760+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 75.7, + "water_total": 967.0, + "average_temperature": 29.6, + "experience_temperature": 21.4829, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:40:07.512643+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 75.7, + "water_total": 976.0, + "average_temperature": 29.8667, + "experience_temperature": 22.7781, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T10:50:09.672971+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 73.8, + "water_total": 991.0, + "average_temperature": 30.0, + "experience_temperature": 22.1886, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:00:07.314800+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.9, + "humidity": 74.8, + "water_total": 1001.0, + "average_temperature": 29.9, + "experience_temperature": 20.9171, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:10:06.518769+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.9, + "humidity": 74.4, + "water_total": 1016.0, + "average_temperature": 30.1, + "experience_temperature": 21.0371, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:20:07.985235+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 72.9, + "water_total": 1030.0, + "average_temperature": 30.8333, + "experience_temperature": 23.5276, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:30:09.551173+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 74.1, + "water_total": 1045.0, + "average_temperature": 30.7, + "experience_temperature": 23.6343, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:40:06.657283+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 73.8, + "water_total": 1057.0, + "average_temperature": 30.2667, + "experience_temperature": 21.7695, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T11:50:07.890496+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.8, + "humidity": 74.3, + "water_total": 1069.0, + "average_temperature": 30.1, + "experience_temperature": 21.36, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:00:11.294492+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.6, + "humidity": 73.3, + "water_total": 1079.0, + "average_temperature": 30.5, + "experience_temperature": 22.2457, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:10:08.144856+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.8, + "humidity": 72.8, + "water_total": 1088.0, + "average_temperature": 30.3667, + "experience_temperature": 21.3267, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:20:07.279181+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.9, + "humidity": 71.6, + "water_total": 1098.0, + "average_temperature": 30.8667, + "experience_temperature": 21.2438, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:30:06.867670+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 71.7, + "water_total": 1108.0, + "average_temperature": 30.5333, + "experience_temperature": 21.6162, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:40:07.253177+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 71.9, + "water_total": 1115.0, + "average_temperature": 30.4, + "experience_temperature": 21.5229, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T12:50:07.357448+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.0, + "humidity": 72.0, + "water_total": 1122.0, + "average_temperature": 30.8, + "experience_temperature": 20.9143, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:00:06.871776+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 70.3, + "water_total": 1132.0, + "average_temperature": 30.9333, + "experience_temperature": 21.7362, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:10:07.730664+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 73.6, + "water_total": 1144.0, + "average_temperature": 31.0, + "experience_temperature": 23.4914, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:20:07.702602+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 70.5, + "water_total": 1157.0, + "average_temperature": 30.7, + "experience_temperature": 24.2857, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:30:06.781272+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 73.7, + "water_total": 1167.0, + "average_temperature": 30.7, + "experience_temperature": 22.1829, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:40:06.551254+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 73.7, + "water_total": 1167.0, + "average_temperature": 30.7, + "experience_temperature": 22.1829, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T13:50:06.719111+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 72.7, + "water_total": 1182.0, + "average_temperature": 30.8, + "experience_temperature": 22.7686, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T14:10:06.535580+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 70.2, + "water_total": 1203.0, + "average_temperature": 31.0333, + "experience_temperature": 23.1876, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T14:20:09.037729+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.8, + "humidity": 75.0, + "water_total": 1213.0, + "average_temperature": 30.5, + "experience_temperature": 21.9, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T14:30:07.725349+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 72.2, + "water_total": 1223.0, + "average_temperature": 30.8667, + "experience_temperature": 22.7352, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T14:40:06.611753+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 73.2, + "water_total": 1233.0, + "average_temperature": 31.0333, + "experience_temperature": 23.4448, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T14:50:07.648650+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.2, + "humidity": 72.9, + "water_total": 1243.0, + "average_temperature": 30.8667, + "experience_temperature": 20.4752, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T15:10:08.520543+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.1, + "humidity": 74.3, + "water_total": 1258.0, + "average_temperature": 30.2, + "experience_temperature": 20.4314, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T15:20:06.657135+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.6, + "humidity": 74.1, + "water_total": 1263.0, + "average_temperature": 30.4667, + "experience_temperature": 22.3724, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T15:30:08.172329+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.8, + "humidity": 72.5, + "water_total": 1268.0, + "average_temperature": 30.9, + "experience_temperature": 21.8, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T15:40:06.956407+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 73.8, + "water_total": 1279.0, + "average_temperature": 30.6, + "experience_temperature": 22.7886, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T15:50:06.782757+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 75.6, + "water_total": 1283.0, + "average_temperature": 30.2, + "experience_temperature": 22.0629, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T16:10:07.357845+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.9, + "humidity": 75.1, + "water_total": 1293.0, + "average_temperature": 30.2667, + "experience_temperature": 21.3438, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T16:20:06.710425+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.7, + "humidity": 75.5, + "water_total": 1303.0, + "average_temperature": 30.1333, + "experience_temperature": 21.9762, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T16:30:07.215793+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 76.5, + "water_total": 1308.0, + "average_temperature": 29.8667, + "experience_temperature": 22.5952, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T16:40:06.724266+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 77.6, + "water_total": 1318.0, + "average_temperature": 29.7, + "experience_temperature": 22.6486, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T16:50:07.278786+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 80.8, + "water_total": 1329.0, + "average_temperature": 29.0333, + "experience_temperature": 22.9648, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T17:10:07.876316+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 80.8, + "water_total": 1329.0, + "average_temperature": 29.0333, + "experience_temperature": 22.9648, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T17:20:07.932997+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 84.5, + "water_total": 24.0, + "average_temperature": 28.3333, + "experience_temperature": 22.6619, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T17:30:06.213998+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 84.4, + "water_total": 126.0, + "average_temperature": 28.6, + "experience_temperature": 22.9086, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T17:40:07.185681+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 85.0, + "water_total": 258.0, + "average_temperature": 28.3, + "experience_temperature": 23.0714, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T17:50:06.335686+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.0, + "humidity": 85.3, + "water_total": 398.0, + "average_temperature": 28.2333, + "experience_temperature": 24.4362, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:00:07.915663+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.2, + "humidity": 85.9, + "water_total": 534.0, + "average_temperature": 27.9667, + "experience_temperature": 23.6038, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:10:08.340184+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 85.8, + "water_total": 671.0, + "average_temperature": 28.0333, + "experience_temperature": 22.9648, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:20:06.000539+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 86.2, + "water_total": 808.0, + "average_temperature": 28.2, + "experience_temperature": 23.5543, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:30:05.069749+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.4, + "humidity": 84.6, + "water_total": 941.0, + "average_temperature": 28.4667, + "experience_temperature": 23.1581, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:40:08.376484+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.8, + "humidity": 84.0, + "water_total": 1001.0, + "average_temperature": 28.4, + "experience_temperature": 21.6, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T18:50:05.578542+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 85.9, + "water_total": 1016.0, + "average_temperature": 28.1, + "experience_temperature": 22.7086, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:00:05.991995+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.2, + "humidity": 86.5, + "water_total": 1036.0, + "average_temperature": 27.9667, + "experience_temperature": 23.7238, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:10:06.311703+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 84.4, + "water_total": 1045.0, + "average_temperature": 28.0667, + "experience_temperature": 22.3752, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:20:06.088781+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 84.2, + "water_total": 1060.0, + "average_temperature": 28.1667, + "experience_temperature": 22.4352, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:30:06.783017+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 83.9, + "water_total": 1067.0, + "average_temperature": 27.9667, + "experience_temperature": 22.1752, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:40:07.342444+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.5, + "humidity": 85.9, + "water_total": 1079.0, + "average_temperature": 28.0333, + "experience_temperature": 22.6419, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T19:50:06.192666+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.1, + "humidity": 85.9, + "water_total": 1088.0, + "average_temperature": 27.7, + "experience_temperature": 23.68, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T20:00:07.519721+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.3, + "humidity": 80.9, + "water_total": 1093.0, + "average_temperature": 27.7333, + "experience_temperature": 22.0276, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T20:20:08.510597+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.1, + "humidity": 79.7, + "water_total": 1107.0, + "average_temperature": 27.6333, + "experience_temperature": 22.3733, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T20:30:08.457922+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 80.5, + "water_total": 1117.0, + "average_temperature": 27.6, + "experience_temperature": 23.1857, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T20:40:09.864016+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.9, + "humidity": 83.1, + "water_total": 1121.0, + "average_temperature": 26.9, + "experience_temperature": 23.0057, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T20:50:07.034427+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 2.9, + "humidity": 83.2, + "water_total": 1126.0, + "average_temperature": 27.4, + "experience_temperature": 20.0971, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:00:07.051600+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 5.1, + "humidity": 83.6, + "water_total": 1126.0, + "average_temperature": 27.1667, + "experience_temperature": 12.401, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:10:05.211609+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.0, + "humidity": 84.3, + "water_total": 1130.0, + "average_temperature": 26.9333, + "experience_temperature": 19.5076, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:20:05.379167+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.8, + "humidity": 87.4, + "water_total": 1130.0, + "average_temperature": 26.6, + "experience_temperature": 17.0514, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:30:05.749268+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.6, + "humidity": 88.2, + "water_total": 1135.0, + "average_temperature": 26.4667, + "experience_temperature": 17.7638, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:40:08.225090+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 3.4, + "humidity": 87.7, + "water_total": 1150.0, + "average_temperature": 26.3333, + "experience_temperature": 18.2162, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T21:50:05.993254+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 87.5, + "water_total": 1170.0, + "average_temperature": 26.3667, + "experience_temperature": 24.381, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:00:05.360189+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 87.5, + "water_total": 1170.0, + "average_temperature": 26.3667, + "experience_temperature": 24.381, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:10:05.876166+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 87.4, + "water_total": 1189.0, + "average_temperature": 26.5, + "experience_temperature": 24.4943, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:20:05.960153+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.6, + "humidity": 87.4, + "water_total": 1189.0, + "average_temperature": 26.5, + "experience_temperature": 24.4943, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:30:06.342091+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.7, + "humidity": 88.3, + "water_total": 1198.0, + "average_temperature": 26.3, + "experience_temperature": 24.1314, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:40:07.556968+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.3, + "humidity": 88.6, + "water_total": 1208.0, + "average_temperature": 26.2, + "experience_temperature": 25.4629, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T22:50:06.923962+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.7, + "humidity": 88.6, + "water_total": 1213.0, + "average_temperature": 26.1, + "experience_temperature": 23.9914, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:00:06.192351+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.7, + "humidity": 88.8, + "water_total": 1222.0, + "average_temperature": 26.0667, + "experience_temperature": 23.9981, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:10:05.558463+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.5, + "humidity": 89.2, + "water_total": 1227.0, + "average_temperature": 26.1, + "experience_temperature": 24.7971, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:20:05.605186+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.8, + "humidity": 89.7, + "water_total": 1232.0, + "average_temperature": 25.9333, + "experience_temperature": 23.7019, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:30:07.075932+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 1237.0, + "average_temperature": 25.9, + "experience_temperature": 25.7857, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:40:05.805616+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.2, + "humidity": 90.2, + "water_total": 1242.0, + "average_temperature": 25.9333, + "experience_temperature": 25.859, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-26T23:50:05.612659+07:00", + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.1, + "humidity": 90.2, + "water_total": 1247.0, + "average_temperature": 25.8333, + "experience_temperature": 26.1019, + "chill_factor": 3.4286 + }, + { + "timestamp": "2026-06-27T00:00:05.437912+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.1, + "humidity": 90.2, + "water_total": 1247.0, + "average_temperature": 25.8333, + "experience_temperature": 26.1805, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T00:10:05.291489+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 90.4, + "water_total": 1256.0, + "average_temperature": 25.7667, + "experience_temperature": 25.8181, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T00:20:05.994332+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 1261.0, + "average_temperature": 25.8333, + "experience_temperature": 25.9448, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T00:30:06.039731+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.1, + "humidity": 90.5, + "water_total": 1271.0, + "average_temperature": 25.8, + "experience_temperature": 26.2071, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T00:40:06.435619+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 1276.0, + "average_temperature": 25.7333, + "experience_temperature": 25.8448, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T00:50:06.664407+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 1281.0, + "average_temperature": 25.6333, + "experience_temperature": 25.7848, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:00:05.699424+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 1281.0, + "average_temperature": 25.6333, + "experience_temperature": 25.7848, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:10:05.797799+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 91.0, + "water_total": 1290.0, + "average_temperature": 25.4333, + "experience_temperature": 25.269, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:20:05.778780+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 91.7, + "water_total": 1295.0, + "average_temperature": 25.3667, + "experience_temperature": 25.3424, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:30:05.366540+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 1300.0, + "average_temperature": 25.4, + "experience_temperature": 25.6914, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:40:06.050766+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 91.9, + "water_total": 1304.0, + "average_temperature": 25.4667, + "experience_temperature": 25.4824, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T01:50:06.565355+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 92.3, + "water_total": 1313.0, + "average_temperature": 25.4, + "experience_temperature": 25.8314, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:00:07.474327+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 1318.0, + "average_temperature": 25.4333, + "experience_temperature": 25.8248, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:10:05.582154+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 92.3, + "water_total": 1323.0, + "average_temperature": 25.1667, + "experience_temperature": 25.5981, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:20:05.953599+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 1328.0, + "average_temperature": 25.2, + "experience_temperature": 25.7314, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:30:05.598354+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 92.7, + "water_total": 1333.0, + "average_temperature": 25.1, + "experience_temperature": 25.2757, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:40:05.898523+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.0, + "water_total": 1337.0, + "average_temperature": 25.1667, + "experience_temperature": 25.7381, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T02:50:05.834657+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.0, + "water_total": 1342.0, + "average_temperature": 25.0, + "experience_temperature": 25.5714, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:00:06.281172+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.3, + "water_total": 1347.0, + "average_temperature": 24.9, + "experience_temperature": 25.5314, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:10:05.977718+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.5, + "water_total": 1351.0, + "average_temperature": 24.9333, + "experience_temperature": 25.6048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:20:05.827236+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.1, + "humidity": 93.5, + "water_total": 1356.0, + "average_temperature": 24.8, + "experience_temperature": 25.8071, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:30:06.629790+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.5, + "water_total": 1362.0, + "average_temperature": 24.7333, + "experience_temperature": 25.4048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:40:06.201774+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.6, + "water_total": 1367.0, + "average_temperature": 24.6, + "experience_temperature": 25.2914, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T03:50:06.073164+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.6, + "water_total": 1367.0, + "average_temperature": 24.6, + "experience_temperature": 25.2914, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:00:06.033659+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1377.0, + "average_temperature": 24.5333, + "experience_temperature": 25.3048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:10:06.143956+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1381.0, + "average_temperature": 24.5667, + "experience_temperature": 25.3381, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:20:06.019647+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1386.0, + "average_temperature": 24.5333, + "experience_temperature": 25.3048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:30:06.614883+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.1, + "water_total": 1386.0, + "average_temperature": 24.4667, + "experience_temperature": 25.2581, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:40:06.013860+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1396.0, + "average_temperature": 24.4333, + "experience_temperature": 25.2048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T04:50:05.747716+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 94.0, + "water_total": 1401.0, + "average_temperature": 24.2667, + "experience_temperature": 24.7024, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:00:06.238354+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1401.0, + "average_temperature": 24.2, + "experience_temperature": 24.9714, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:10:06.577440+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.2, + "water_total": 1406.0, + "average_temperature": 24.3, + "experience_temperature": 25.1114, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:20:05.936484+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.2, + "water_total": 1410.0, + "average_temperature": 24.4, + "experience_temperature": 25.2114, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:30:06.324724+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.2, + "water_total": 1410.0, + "average_temperature": 24.4, + "experience_temperature": 25.2114, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:40:05.826403+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.1, + "water_total": 1419.0, + "average_temperature": 24.3667, + "experience_temperature": 25.1581, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T05:50:05.740274+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1424.0, + "average_temperature": 24.3667, + "experience_temperature": 25.1381, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:00:08.587219+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 94.0, + "water_total": 1429.0, + "average_temperature": 24.3, + "experience_temperature": 24.7357, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:10:06.869611+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.3, + "humidity": 94.1, + "water_total": 1433.0, + "average_temperature": 24.3, + "experience_temperature": 24.7557, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:20:07.186239+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1443.0, + "average_temperature": 24.3667, + "experience_temperature": 25.1381, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:30:06.574496+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1443.0, + "average_temperature": 24.4333, + "experience_temperature": 25.2048, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:40:06.304770+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.9, + "water_total": 1468.0, + "average_temperature": 24.4667, + "experience_temperature": 25.2181, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T06:50:06.076747+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 1516.0, + "average_temperature": 24.6, + "experience_temperature": 25.3714, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:00:06.079677+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.7, + "water_total": 1575.0, + "average_temperature": 24.8667, + "experience_temperature": 25.5781, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:10:06.234878+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.2, + "humidity": 93.2, + "water_total": 1635.0, + "average_temperature": 25.0667, + "experience_temperature": 25.6781, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:20:07.124738+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.1, + "humidity": 93.3, + "water_total": 1647.0, + "average_temperature": 25.4667, + "experience_temperature": 26.4338, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:30:06.745850+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.1, + "humidity": 93.3, + "water_total": 1647.0, + "average_temperature": 25.4667, + "experience_temperature": 26.4338, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:40:06.055637+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 92.0, + "water_total": 1661.0, + "average_temperature": 25.8333, + "experience_temperature": 24.8619, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T07:50:06.172200+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 91.5, + "water_total": 1665.0, + "average_temperature": 26.1, + "experience_temperature": 24.6929, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:00:06.353681+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 91.5, + "water_total": 1665.0, + "average_temperature": 26.1, + "experience_temperature": 24.6929, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:10:06.168070+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 90.5, + "water_total": 1680.0, + "average_temperature": 26.4667, + "experience_temperature": 24.8595, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:20:07.457652+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 89.6, + "water_total": 1689.0, + "average_temperature": 27.0, + "experience_temperature": 24.8771, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:30:06.871969+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.5, + "humidity": 85.7, + "water_total": 1709.0, + "average_temperature": 27.8667, + "experience_temperature": 25.971, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:40:08.688023+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 85.0, + "water_total": 1718.0, + "average_temperature": 28.1667, + "experience_temperature": 25.4595, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T08:50:06.225406+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 82.6, + "water_total": 1760.0, + "average_temperature": 28.4, + "experience_temperature": 24.8771, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:00:07.010545+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.9, + "humidity": 82.7, + "water_total": 1843.0, + "average_temperature": 28.8667, + "experience_temperature": 25.0281, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:10:06.155404+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.0, + "humidity": 82.7, + "water_total": 1843.0, + "average_temperature": 28.9, + "experience_temperature": 24.7257, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:20:06.248082+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.9, + "humidity": 80.0, + "water_total": 2155.0, + "average_temperature": 29.5333, + "experience_temperature": 25.1548, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:30:06.769023+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 78.6, + "water_total": 2359.0, + "average_temperature": 30.0333, + "experience_temperature": 23.6962, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:40:06.492697+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.3, + "humidity": 74.7, + "water_total": 2520.0, + "average_temperature": 29.9, + "experience_temperature": 23.1186, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T09:50:06.378849+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 75.8, + "water_total": 2656.0, + "average_temperature": 30.2667, + "experience_temperature": 23.0338, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:00:06.540983+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 73.2, + "water_total": 2739.0, + "average_temperature": 30.3667, + "experience_temperature": 22.9495, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:10:07.058779+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 74.3, + "water_total": 2830.0, + "average_temperature": 31.0333, + "experience_temperature": 24.5076, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:20:07.644027+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.5, + "water_total": 2914.0, + "average_temperature": 30.8667, + "experience_temperature": 22.7738, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:30:05.847841+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.5, + "water_total": 2914.0, + "average_temperature": 30.8667, + "experience_temperature": 22.7738, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:40:09.708555+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.4, + "water_total": 3077.0, + "average_temperature": 30.9667, + "experience_temperature": 22.8538, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T10:50:07.341604+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.0, + "water_total": 3175.0, + "average_temperature": 31.2667, + "experience_temperature": 23.0738, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:00:06.695602+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.0, + "water_total": 3175.0, + "average_temperature": 31.2667, + "experience_temperature": 23.0738, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:10:06.590941+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.3, + "humidity": 72.3, + "water_total": 3348.0, + "average_temperature": 31.2667, + "experience_temperature": 24.0052, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:20:07.477513+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.2, + "water_total": 3439.0, + "average_temperature": 30.9667, + "experience_temperature": 22.8138, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:30:06.256216+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.5, + "water_total": 3517.0, + "average_temperature": 30.6667, + "experience_temperature": 22.5738, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:40:07.251676+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 70.6, + "water_total": 3612.0, + "average_temperature": 30.5, + "experience_temperature": 22.2271, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T11:50:06.650273+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.6, + "humidity": 71.1, + "water_total": 3691.0, + "average_temperature": 30.6333, + "experience_temperature": 22.1248, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:00:09.211285+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 70.2, + "water_total": 3777.0, + "average_temperature": 31.2, + "experience_temperature": 22.8471, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:10:06.888496+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.6, + "water_total": 3861.0, + "average_temperature": 31.0, + "experience_temperature": 22.9271, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:20:06.238503+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 70.7, + "water_total": 3953.0, + "average_temperature": 30.9, + "experience_temperature": 22.6471, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:30:06.386390+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 70.4, + "water_total": 4041.0, + "average_temperature": 30.8333, + "experience_temperature": 23.5276, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:40:07.206764+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 68.9, + "water_total": 4129.0, + "average_temperature": 30.9667, + "experience_temperature": 22.3538, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T12:50:06.083432+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 68.3, + "water_total": 4206.0, + "average_temperature": 31.2333, + "experience_temperature": 22.8362, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:00:07.134844+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.8, + "humidity": 69.1, + "water_total": 4290.0, + "average_temperature": 31.9667, + "experience_temperature": 22.3867, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:10:07.103213+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 69.9, + "water_total": 4382.0, + "average_temperature": 31.0333, + "experience_temperature": 23.6276, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:20:08.792186+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 70.1, + "water_total": 4456.0, + "average_temperature": 30.8667, + "experience_temperature": 22.8295, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:30:07.867200+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 68.6, + "water_total": 4549.0, + "average_temperature": 31.2333, + "experience_temperature": 23.5676, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:40:19.909289+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 68.6, + "water_total": 4549.0, + "average_temperature": 31.2333, + "experience_temperature": 23.5676, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T13:50:06.949495+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 71.6, + "water_total": 4725.0, + "average_temperature": 31.6667, + "experience_temperature": 23.9295, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T14:10:07.018135+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 67.9, + "water_total": 4891.0, + "average_temperature": 31.2, + "experience_temperature": 22.7229, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T14:20:08.989866+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 67.9, + "water_total": 4913.0, + "average_temperature": 31.3333, + "experience_temperature": 22.5205, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T14:30:06.982081+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 69.7, + "water_total": 4926.0, + "average_temperature": 30.9667, + "experience_temperature": 22.5138, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T14:40:05.941122+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 72.8, + "water_total": 4934.0, + "average_temperature": 31.3333, + "experience_temperature": 23.5005, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T14:50:08.615567+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 70.6, + "water_total": 4944.0, + "average_temperature": 31.4667, + "experience_temperature": 23.5295, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T15:10:06.809415+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 71.1, + "water_total": 4960.0, + "average_temperature": 31.2, + "experience_temperature": 23.0271, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T15:20:06.662557+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 70.3, + "water_total": 4971.0, + "average_temperature": 31.2333, + "experience_temperature": 22.9005, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T15:30:07.027630+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 69.3, + "water_total": 4976.0, + "average_temperature": 31.4333, + "experience_temperature": 22.9005, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T15:40:07.859566+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.3, + "humidity": 74.6, + "water_total": 4987.0, + "average_temperature": 30.7333, + "experience_temperature": 23.9319, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T15:50:06.826268+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 75.0, + "water_total": 4991.0, + "average_temperature": 30.2667, + "experience_temperature": 23.2095, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T16:10:08.942443+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 76.4, + "water_total": 5006.0, + "average_temperature": 30.4333, + "experience_temperature": 23.6562, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T16:20:07.216919+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.3, + "humidity": 76.7, + "water_total": 5011.0, + "average_temperature": 30.3, + "experience_temperature": 23.9186, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T16:30:06.606762+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 77.6, + "water_total": 5016.0, + "average_temperature": 30.2667, + "experience_temperature": 23.7295, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T16:40:05.977926+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 77.8, + "water_total": 5124.0, + "average_temperature": 30.2333, + "experience_temperature": 23.7362, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T16:50:06.578487+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.4, + "humidity": 78.2, + "water_total": 5255.0, + "average_temperature": 30.3333, + "experience_temperature": 23.9162, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T17:10:06.939095+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.5, + "humidity": 80.3, + "water_total": 182.0, + "average_temperature": 29.9, + "experience_temperature": 23.5671, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T17:20:06.896345+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.9, + "humidity": 80.2, + "water_total": 366.0, + "average_temperature": 29.6333, + "experience_temperature": 25.2948, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T17:30:06.839819+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.1, + "humidity": 80.8, + "water_total": 549.0, + "average_temperature": 29.2667, + "experience_temperature": 24.3767, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T17:40:06.661709+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.1, + "humidity": 81.5, + "water_total": 678.0, + "average_temperature": 29.0667, + "experience_temperature": 24.3167, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T17:50:06.966817+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.1, + "humidity": 81.8, + "water_total": 678.0, + "average_temperature": 28.9333, + "experience_temperature": 24.2433, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:00:06.472978+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.0, + "humidity": 81.6, + "water_total": 731.0, + "average_temperature": 29.0, + "experience_temperature": 24.6057, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:10:07.857979+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 2.2, + "humidity": 82.2, + "water_total": 829.0, + "average_temperature": 28.8, + "experience_temperature": 23.8543, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:20:06.480595+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 81.7, + "water_total": 912.0, + "average_temperature": 28.6667, + "experience_temperature": 24.9638, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:30:09.214706+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 81.9, + "water_total": 1008.0, + "average_temperature": 28.5333, + "experience_temperature": 25.5419, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:40:08.244729+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.9, + "humidity": 81.6, + "water_total": 1105.0, + "average_temperature": 28.4333, + "experience_temperature": 24.3748, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T18:50:06.729926+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 81.5, + "water_total": 1200.0, + "average_temperature": 28.3333, + "experience_temperature": 24.9262, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:00:06.188720+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 82.5, + "water_total": 1299.0, + "average_temperature": 28.3, + "experience_temperature": 24.7571, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:10:05.940372+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 83.5, + "water_total": 1398.0, + "average_temperature": 28.1667, + "experience_temperature": 25.1595, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:20:06.960438+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 84.3, + "water_total": 1491.0, + "average_temperature": 28.0333, + "experience_temperature": 25.1862, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:30:06.474102+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 83.9, + "water_total": 1585.0, + "average_temperature": 28.2333, + "experience_temperature": 24.9705, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:40:06.537900+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 85.8, + "water_total": 1679.0, + "average_temperature": 27.8667, + "experience_temperature": 24.9838, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T19:50:07.471077+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 87.3, + "water_total": 1776.0, + "average_temperature": 27.6, + "experience_temperature": 25.6886, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T20:00:06.777255+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 87.3, + "water_total": 1776.0, + "average_temperature": 27.6, + "experience_temperature": 25.6886, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T20:10:09.047583+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 88.1, + "water_total": 1974.0, + "average_temperature": 27.5333, + "experience_temperature": 25.1105, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T20:20:06.869436+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.9, + "humidity": 88.0, + "water_total": 2070.0, + "average_temperature": 27.5, + "experience_temperature": 24.7214, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T20:30:06.528133+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 2163.0, + "average_temperature": 27.4333, + "experience_temperature": 25.3062, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T20:40:06.930578+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 88.4, + "water_total": 2255.0, + "average_temperature": 27.3333, + "experience_temperature": 25.3062, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:00:09.217862+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 88.9, + "water_total": 2455.0, + "average_temperature": 27.0, + "experience_temperature": 25.4086, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:10:05.488993+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 89.2, + "water_total": 2543.0, + "average_temperature": 27.0, + "experience_temperature": 25.4686, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:20:05.983715+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 89.5, + "water_total": 2633.0, + "average_temperature": 27.0667, + "experience_temperature": 25.5952, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:30:06.466583+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 90.1, + "water_total": 2738.0, + "average_temperature": 27.1, + "experience_temperature": 25.7486, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:40:06.802523+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 90.4, + "water_total": 2816.0, + "average_temperature": 26.9667, + "experience_temperature": 25.3395, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T21:50:05.983722+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.5, + "humidity": 90.9, + "water_total": 2923.0, + "average_temperature": 26.9, + "experience_temperature": 26.0443, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:00:06.011987+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 91.2, + "water_total": 3012.0, + "average_temperature": 26.8667, + "experience_temperature": 25.0638, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:10:07.347337+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 91.6, + "water_total": 3110.0, + "average_temperature": 26.9333, + "experience_temperature": 25.5462, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:20:06.049623+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.5, + "humidity": 91.6, + "water_total": 3199.0, + "average_temperature": 26.8, + "experience_temperature": 26.0843, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:30:06.311066+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 91.7, + "water_total": 3295.0, + "average_temperature": 26.7667, + "experience_temperature": 25.0638, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:40:06.588781+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 91.9, + "water_total": 3386.0, + "average_temperature": 26.5667, + "experience_temperature": 24.9038, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T22:50:07.255506+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 91.9, + "water_total": 3481.0, + "average_temperature": 26.6667, + "experience_temperature": 25.6752, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:00:07.038568+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 92.1, + "water_total": 3569.0, + "average_temperature": 26.6667, + "experience_temperature": 25.7152, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:10:06.229704+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 92.1, + "water_total": 3569.0, + "average_temperature": 26.6667, + "experience_temperature": 25.7152, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:20:06.563620+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 92.3, + "water_total": 3766.0, + "average_temperature": 26.6667, + "experience_temperature": 25.7552, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:30:06.732489+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.7, + "humidity": 92.2, + "water_total": 3856.0, + "average_temperature": 26.6667, + "experience_temperature": 25.3995, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:40:07.222106+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.6, + "humidity": 92.3, + "water_total": 3972.0, + "average_temperature": 26.7333, + "experience_temperature": 25.8219, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-27T23:50:07.050738+07:00", + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 92.3, + "water_total": 4069.0, + "average_temperature": 26.6667, + "experience_temperature": 25.0838, + "chill_factor": 3.3571 + }, + { + "timestamp": "2026-06-28T00:00:06.501160+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 92.6, + "water_total": 4089.0, + "average_temperature": 26.5333, + "experience_temperature": 25.4676, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T00:10:07.136484+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 92.8, + "water_total": 4104.0, + "average_temperature": 26.5333, + "experience_temperature": 25.5076, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T00:20:07.293732+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 92.7, + "water_total": 4117.0, + "average_temperature": 26.5, + "experience_temperature": 25.4543, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T00:30:06.224123+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 92.9, + "water_total": 4132.0, + "average_temperature": 26.1667, + "experience_temperature": 25.8181, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T00:40:06.204165+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.8, + "humidity": 93.3, + "water_total": 4146.0, + "average_temperature": 26.1333, + "experience_temperature": 24.879, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T00:50:06.541480+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 93.6, + "water_total": 4160.0, + "average_temperature": 26.1333, + "experience_temperature": 25.2676, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:00:08.038757+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 93.6, + "water_total": 4169.0, + "average_temperature": 26.1, + "experience_temperature": 25.5629, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:10:07.188095+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 93.9, + "water_total": 4179.0, + "average_temperature": 26.1667, + "experience_temperature": 25.361, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:20:06.037774+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 93.9, + "water_total": 4188.0, + "average_temperature": 26.1, + "experience_temperature": 25.9514, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:30:06.348303+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 94.0, + "water_total": 4197.0, + "average_temperature": 25.9667, + "experience_temperature": 25.5095, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:40:06.216219+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 94.0, + "water_total": 4207.0, + "average_temperature": 25.9667, + "experience_temperature": 25.181, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T01:50:06.418221+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.8, + "humidity": 94.2, + "water_total": 4216.0, + "average_temperature": 25.9667, + "experience_temperature": 24.8924, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:00:06.319062+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.8, + "humidity": 94.2, + "water_total": 4216.0, + "average_temperature": 25.9667, + "experience_temperature": 24.8924, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:10:05.827715+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 94.4, + "water_total": 4238.0, + "average_temperature": 25.9333, + "experience_temperature": 25.2276, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:20:05.982923+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 94.3, + "water_total": 4244.0, + "average_temperature": 25.9, + "experience_temperature": 24.5171, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:30:05.534609+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 94.3, + "water_total": 4244.0, + "average_temperature": 25.9, + "experience_temperature": 24.5171, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:40:06.297897+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 94.5, + "water_total": 4264.0, + "average_temperature": 25.8333, + "experience_temperature": 25.4762, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T02:50:06.402435+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 94.4, + "water_total": 4273.0, + "average_temperature": 25.8, + "experience_temperature": 25.0943, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T03:10:05.663787+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.6, + "water_total": 4297.0, + "average_temperature": 25.7667, + "experience_temperature": 26.7438, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T03:20:06.451069+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.4, + "water_total": 4307.0, + "average_temperature": 25.5333, + "experience_temperature": 26.1419, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T03:30:06.115661+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.3, + "water_total": 4316.0, + "average_temperature": 25.5667, + "experience_temperature": 26.1552, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T03:40:07.045881+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.2, + "water_total": 4326.0, + "average_temperature": 25.4333, + "experience_temperature": 26.3305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T03:50:06.252224+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.3, + "water_total": 4335.0, + "average_temperature": 25.3, + "experience_temperature": 26.2171, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:00:06.499681+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.3, + "water_total": 4345.0, + "average_temperature": 25.1333, + "experience_temperature": 25.7219, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:10:06.402356+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.2, + "water_total": 4354.0, + "average_temperature": 25.1, + "experience_temperature": 25.6686, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:20:06.809856+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.4, + "water_total": 4361.0, + "average_temperature": 25.0667, + "experience_temperature": 25.6752, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:30:06.127768+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.4, + "water_total": 4373.0, + "average_temperature": 25.0333, + "experience_temperature": 25.9705, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:40:05.605181+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.3, + "water_total": 4382.0, + "average_temperature": 24.9333, + "experience_temperature": 25.5219, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T04:50:06.125244+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.4, + "water_total": 4392.0, + "average_temperature": 24.9667, + "experience_temperature": 25.9038, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:00:06.024396+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.4, + "water_total": 4402.0, + "average_temperature": 24.9667, + "experience_temperature": 25.9038, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:10:06.199929+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 94.2, + "water_total": 4411.0, + "average_temperature": 24.6333, + "experience_temperature": 24.8733, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:20:06.739409+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.7, + "water_total": 4421.0, + "average_temperature": 24.7333, + "experience_temperature": 25.4019, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:30:06.757875+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 94.3, + "water_total": 4430.0, + "average_temperature": 24.6333, + "experience_temperature": 24.8933, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:40:06.168380+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.8, + "water_total": 4440.0, + "average_temperature": 24.6333, + "experience_temperature": 25.3219, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T05:50:05.879373+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.5, + "water_total": 4445.0, + "average_temperature": 24.5, + "experience_temperature": 25.4571, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:00:07.416454+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.7, + "water_total": 4459.0, + "average_temperature": 24.6333, + "experience_temperature": 25.6305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:10:07.451498+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 94.6, + "water_total": 4468.0, + "average_temperature": 24.4, + "experience_temperature": 25.3771, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:20:06.710222+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 94.9, + "water_total": 4478.0, + "average_temperature": 24.5333, + "experience_temperature": 25.2419, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:30:06.869237+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 94.7, + "water_total": 4491.0, + "average_temperature": 24.5667, + "experience_temperature": 24.9067, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:40:07.308976+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 95.1, + "water_total": 4501.0, + "average_temperature": 24.6667, + "experience_temperature": 25.7438, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T06:50:07.417578+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 95.0, + "water_total": 4513.0, + "average_temperature": 24.8333, + "experience_temperature": 25.5619, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:00:07.163915+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 95.1, + "water_total": 4525.0, + "average_temperature": 24.8667, + "experience_temperature": 25.9438, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:10:07.623487+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.3, + "humidity": 95.2, + "water_total": 4534.0, + "average_temperature": 25.0667, + "experience_temperature": 25.8352, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:20:06.141931+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 95.1, + "water_total": 4544.0, + "average_temperature": 25.2, + "experience_temperature": 25.62, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:30:05.663210+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 95.2, + "water_total": 4558.0, + "average_temperature": 25.5333, + "experience_temperature": 26.6305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:40:06.371350+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 95.2, + "water_total": 4558.0, + "average_temperature": 25.5333, + "experience_temperature": 26.6305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T07:50:07.984772+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 94.6, + "water_total": 4585.0, + "average_temperature": 25.8, + "experience_temperature": 24.4771, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:00:06.271383+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 93.8, + "water_total": 4596.0, + "average_temperature": 26.1, + "experience_temperature": 25.6029, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:10:08.831733+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 93.8, + "water_total": 4596.0, + "average_temperature": 26.1, + "experience_temperature": 25.6029, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:20:07.105649+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 92.3, + "water_total": 4606.0, + "average_temperature": 26.2667, + "experience_temperature": 25.4695, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:30:09.314284+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.8, + "humidity": 87.5, + "water_total": 4625.0, + "average_temperature": 27.0667, + "experience_temperature": 24.6524, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:40:05.813125+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 84.5, + "water_total": 4721.0, + "average_temperature": 27.7667, + "experience_temperature": 25.4095, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T08:50:06.415293+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.8, + "humidity": 81.8, + "water_total": 4875.0, + "average_temperature": 28.4667, + "experience_temperature": 24.9124, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:00:06.067743+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 79.7, + "water_total": 5102.0, + "average_temperature": 28.7, + "experience_temperature": 25.3829, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:10:06.306895+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.0, + "humidity": 78.0, + "water_total": 5267.0, + "average_temperature": 29.0333, + "experience_temperature": 24.0619, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:20:08.495094+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.1, + "humidity": 78.4, + "water_total": 5439.0, + "average_temperature": 29.0333, + "experience_temperature": 23.8133, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:30:06.276895+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.3, + "humidity": 78.0, + "water_total": 5606.0, + "average_temperature": 29.3333, + "experience_temperature": 23.3762, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:40:05.909498+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.2, + "humidity": 78.4, + "water_total": 5753.0, + "average_temperature": 29.5667, + "experience_temperature": 24.0181, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T09:50:06.770201+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.2, + "humidity": 77.2, + "water_total": 5853.0, + "average_temperature": 29.6667, + "experience_temperature": 23.8781, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:00:06.036480+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 76.7, + "water_total": 5954.0, + "average_temperature": 30.1333, + "experience_temperature": 23.259, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:10:07.695801+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 75.7, + "water_total": 6048.0, + "average_temperature": 30.5, + "experience_temperature": 23.7543, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:20:06.009264+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 73.3, + "water_total": 6140.0, + "average_temperature": 30.7667, + "experience_temperature": 23.2124, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:30:06.586420+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.6, + "humidity": 71.7, + "water_total": 6246.0, + "average_temperature": 30.6333, + "experience_temperature": 22.4305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:40:05.981792+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 72.0, + "water_total": 6355.0, + "average_temperature": 30.8333, + "experience_temperature": 23.019, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T10:50:06.398710+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.4, + "water_total": 6453.0, + "average_temperature": 31.2, + "experience_temperature": 23.2657, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:00:06.109162+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 70.6, + "water_total": 6563.0, + "average_temperature": 31.2, + "experience_temperature": 23.1057, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:10:06.364123+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 70.2, + "water_total": 6668.0, + "average_temperature": 31.0333, + "experience_temperature": 22.859, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:20:05.939966+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.4, + "water_total": 6758.0, + "average_temperature": 31.5667, + "experience_temperature": 23.6324, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:30:08.676135+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 70.7, + "water_total": 6805.0, + "average_temperature": 31.0333, + "experience_temperature": 23.2876, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:40:07.123742+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 70.7, + "water_total": 6805.0, + "average_temperature": 31.0333, + "experience_temperature": 23.2876, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T11:50:07.627246+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 70.3, + "water_total": 6829.0, + "average_temperature": 31.0333, + "experience_temperature": 23.2076, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:00:06.045601+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 69.2, + "water_total": 6834.0, + "average_temperature": 31.5667, + "experience_temperature": 23.1924, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:10:07.046226+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 69.8, + "water_total": 6844.0, + "average_temperature": 31.2, + "experience_temperature": 22.9457, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:20:07.500760+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.3, + "water_total": 6853.0, + "average_temperature": 31.2667, + "experience_temperature": 23.3124, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:30:06.487880+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 72.0, + "water_total": 6858.0, + "average_temperature": 31.2667, + "experience_temperature": 23.4524, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:40:07.438653+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.9, + "water_total": 6867.0, + "average_temperature": 31.1, + "experience_temperature": 23.2657, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T12:50:06.651432+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 70.6, + "water_total": 6877.0, + "average_temperature": 30.7, + "experience_temperature": 22.6057, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:00:06.326061+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.6, + "humidity": 69.0, + "water_total": 6882.0, + "average_temperature": 30.8667, + "experience_temperature": 22.1238, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:10:06.412478+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.6, + "humidity": 70.0, + "water_total": 6891.0, + "average_temperature": 31.0, + "experience_temperature": 22.4571, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:20:05.928036+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.8, + "humidity": 69.9, + "water_total": 6896.0, + "average_temperature": 31.9, + "experience_temperature": 22.68, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:30:06.616033+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.6, + "water_total": 6906.0, + "average_temperature": 30.9333, + "experience_temperature": 23.039, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:40:06.309934+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 73.6, + "water_total": 6916.0, + "average_temperature": 31.4667, + "experience_temperature": 23.9724, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T13:50:07.318059+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.6, + "humidity": 73.1, + "water_total": 6924.0, + "average_temperature": 31.4667, + "experience_temperature": 23.5438, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T14:10:05.831882+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 75.3, + "water_total": 6939.0, + "average_temperature": 30.9667, + "experience_temperature": 23.8124, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T14:20:06.580939+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 76.4, + "water_total": 6948.0, + "average_temperature": 30.8333, + "experience_temperature": 23.899, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T14:30:06.808735+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 76.4, + "water_total": 6948.0, + "average_temperature": 30.8333, + "experience_temperature": 23.899, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T14:40:06.095126+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 74.1, + "water_total": 6962.0, + "average_temperature": 31.5, + "experience_temperature": 24.1057, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T14:50:06.765667+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 73.5, + "water_total": 6971.0, + "average_temperature": 31.3667, + "experience_temperature": 23.8524, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T15:10:08.622706+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 73.7, + "water_total": 6985.0, + "average_temperature": 30.6667, + "experience_temperature": 23.1924, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T15:20:07.681899+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.6, + "water_total": 6990.0, + "average_temperature": 30.7, + "experience_temperature": 22.8057, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T15:30:06.400066+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 68.7, + "water_total": 7000.0, + "average_temperature": 31.2333, + "experience_temperature": 23.0876, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T15:40:06.522025+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.4, + "humidity": 70.0, + "water_total": 7005.0, + "average_temperature": 30.8, + "experience_temperature": 22.9143, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T15:50:07.631915+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.3, + "humidity": 70.2, + "water_total": 7009.0, + "average_temperature": 30.6, + "experience_temperature": 23.0829, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T16:10:07.066422+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 70.6, + "water_total": 7019.0, + "average_temperature": 30.8667, + "experience_temperature": 22.7724, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T16:20:06.736273+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.5, + "humidity": 71.5, + "water_total": 7019.0, + "average_temperature": 30.6333, + "experience_temperature": 22.719, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T16:30:06.480321+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 3.2, + "humidity": 72.2, + "water_total": 7024.0, + "average_temperature": 30.4667, + "experience_temperature": 20.3924, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T16:40:07.441541+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 74.3, + "water_total": 7029.0, + "average_temperature": 30.2333, + "experience_temperature": 24.8505, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T16:50:06.525474+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 74.7, + "water_total": 7034.0, + "average_temperature": 29.9667, + "experience_temperature": 24.6638, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T17:10:06.785436+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.2, + "humidity": 76.1, + "water_total": 4.0, + "average_temperature": 29.6333, + "experience_temperature": 23.6248, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T17:20:06.463211+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.0, + "humidity": 76.7, + "water_total": 9.0, + "average_temperature": 29.4667, + "experience_temperature": 24.2352, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T17:30:06.502678+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.0, + "humidity": 77.1, + "water_total": 14.0, + "average_temperature": 29.2333, + "experience_temperature": 24.0819, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T17:40:09.567896+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 77.8, + "water_total": 18.0, + "average_temperature": 29.0333, + "experience_temperature": 24.3505, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T17:50:06.793575+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 78.3, + "water_total": 23.0, + "average_temperature": 29.0333, + "experience_temperature": 24.4505, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:00:10.692919+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 2.0, + "humidity": 78.4, + "water_total": 27.0, + "average_temperature": 28.8333, + "experience_temperature": 23.9419, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:10:06.811472+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 77.7, + "water_total": 32.0, + "average_temperature": 28.9333, + "experience_temperature": 24.2305, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:20:07.344477+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.9, + "humidity": 78.4, + "water_total": 32.0, + "average_temperature": 28.7333, + "experience_temperature": 24.1705, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:30:06.655426+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 79.4, + "water_total": 37.0, + "average_temperature": 28.4667, + "experience_temperature": 25.0895, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:40:07.128224+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 80.1, + "water_total": 41.0, + "average_temperature": 28.2667, + "experience_temperature": 25.3581, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T18:50:06.647029+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 78.6, + "water_total": 46.0, + "average_temperature": 28.6, + "experience_temperature": 25.0629, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:00:07.021321+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 79.9, + "water_total": 51.0, + "average_temperature": 28.5667, + "experience_temperature": 25.2895, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:10:06.341481+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 80.1, + "water_total": 56.0, + "average_temperature": 28.4, + "experience_temperature": 25.82, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:20:08.343496+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 80.5, + "water_total": 56.0, + "average_temperature": 28.2, + "experience_temperature": 24.7143, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:30:07.156507+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 81.8, + "water_total": 60.0, + "average_temperature": 27.9, + "experience_temperature": 24.6743, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:40:07.060672+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 82.4, + "water_total": 65.0, + "average_temperature": 27.6667, + "experience_temperature": 24.561, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T19:50:05.905086+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 82.6, + "water_total": 65.0, + "average_temperature": 27.5, + "experience_temperature": 24.7629, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:00:06.281138+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 82.4, + "water_total": 70.0, + "average_temperature": 27.3667, + "experience_temperature": 24.261, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:10:06.080684+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 82.4, + "water_total": 74.0, + "average_temperature": 27.4667, + "experience_temperature": 24.361, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:20:05.548962+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 82.3, + "water_total": 76.0, + "average_temperature": 27.3333, + "experience_temperature": 24.5362, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:30:05.500379+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 82.9, + "water_total": 79.0, + "average_temperature": 27.2333, + "experience_temperature": 24.2276, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:40:05.868910+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 83.4, + "water_total": 84.0, + "average_temperature": 27.0333, + "experience_temperature": 24.4562, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T20:50:05.771414+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 84.1, + "water_total": 84.0, + "average_temperature": 26.7333, + "experience_temperature": 24.2962, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:00:06.676938+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.7, + "humidity": 84.6, + "water_total": 88.0, + "average_temperature": 26.4667, + "experience_temperature": 23.801, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:10:08.486394+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 85.5, + "water_total": 88.0, + "average_temperature": 26.2667, + "experience_temperature": 24.1095, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:20:05.588273+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 86.4, + "water_total": 93.0, + "average_temperature": 26.1667, + "experience_temperature": 24.5181, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:30:06.657087+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 87.0, + "water_total": 98.0, + "average_temperature": 26.1333, + "experience_temperature": 24.6048, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:40:06.537408+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 87.5, + "water_total": 98.0, + "average_temperature": 26.0333, + "experience_temperature": 24.9333, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T21:50:06.927704+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 88.1, + "water_total": 102.0, + "average_temperature": 25.9333, + "experience_temperature": 24.6248, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:00:06.497397+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 88.4, + "water_total": 102.0, + "average_temperature": 25.9333, + "experience_temperature": 25.0133, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:10:06.118556+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 88.6, + "water_total": 106.0, + "average_temperature": 25.9, + "experience_temperature": 24.3629, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:20:07.112390+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 88.9, + "water_total": 106.0, + "average_temperature": 25.8, + "experience_temperature": 24.3229, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:30:06.122830+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.5, + "humidity": 89.3, + "water_total": 111.0, + "average_temperature": 25.7667, + "experience_temperature": 24.6981, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:40:06.426353+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 89.7, + "water_total": 116.0, + "average_temperature": 25.6667, + "experience_temperature": 24.3495, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T22:50:06.732488+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 89.9, + "water_total": 116.0, + "average_temperature": 25.6667, + "experience_temperature": 24.3895, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:00:06.468482+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.6, + "humidity": 89.9, + "water_total": 116.0, + "average_temperature": 25.6667, + "experience_temperature": 24.3895, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:10:06.338983+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.4, + "humidity": 90.2, + "water_total": 120.0, + "average_temperature": 25.6, + "experience_temperature": 25.04, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:20:07.373737+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 90.3, + "water_total": 125.0, + "average_temperature": 25.5333, + "experience_temperature": 25.6505, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:30:06.859967+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 90.5, + "water_total": 129.0, + "average_temperature": 25.4667, + "experience_temperature": 25.6238, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:40:06.238374+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 129.0, + "average_temperature": 25.4, + "experience_temperature": 25.5971, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-28T23:50:06.591156+07:00", + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 134.0, + "average_temperature": 25.3333, + "experience_temperature": 25.5705, + "chill_factor": 3.2857 + }, + { + "timestamp": "2026-06-29T00:00:06.440218+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 91.1, + "water_total": 138.0, + "average_temperature": 25.3, + "experience_temperature": 25.9843, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T00:10:07.108264+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 91.2, + "water_total": 138.0, + "average_temperature": 25.2667, + "experience_temperature": 25.6495, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T00:20:05.822215+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 91.3, + "water_total": 143.0, + "average_temperature": 25.3, + "experience_temperature": 25.7029, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T00:30:07.217314+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 91.3, + "water_total": 143.0, + "average_temperature": 25.2667, + "experience_temperature": 25.6695, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T00:40:06.885907+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 91.6, + "water_total": 148.0, + "average_temperature": 25.2333, + "experience_temperature": 26.0176, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T00:50:06.404727+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 152.0, + "average_temperature": 25.1333, + "experience_temperature": 25.5962, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:00:10.463352+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 91.7, + "water_total": 152.0, + "average_temperature": 25.1333, + "experience_temperature": 25.9376, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:10:06.374112+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 91.7, + "water_total": 157.0, + "average_temperature": 25.0667, + "experience_temperature": 25.871, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:20:06.333177+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 91.8, + "water_total": 157.0, + "average_temperature": 25.0, + "experience_temperature": 25.5029, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:30:06.487405+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 161.0, + "average_temperature": 24.9, + "experience_temperature": 25.4429, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:40:07.040643+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.3, + "humidity": 92.1, + "water_total": 161.0, + "average_temperature": 24.8667, + "experience_temperature": 25.1081, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T01:50:07.339201+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 165.0, + "average_temperature": 24.8333, + "experience_temperature": 25.3962, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:00:06.871401+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 170.0, + "average_temperature": 24.8, + "experience_temperature": 25.3829, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:10:06.700842+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.3, + "water_total": 170.0, + "average_temperature": 24.6667, + "experience_temperature": 25.2695, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:20:06.200492+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.6, + "water_total": 175.0, + "average_temperature": 24.6667, + "experience_temperature": 25.3295, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:30:06.251572+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 175.0, + "average_temperature": 24.6333, + "experience_temperature": 25.3362, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:40:07.091386+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 179.0, + "average_temperature": 24.5667, + "experience_temperature": 25.2695, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T02:50:06.734036+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.9, + "water_total": 179.0, + "average_temperature": 24.5, + "experience_temperature": 25.2229, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:00:07.171051+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.9, + "water_total": 184.0, + "average_temperature": 24.3667, + "experience_temperature": 25.0895, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:10:07.141227+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.0, + "water_total": 184.0, + "average_temperature": 24.3, + "experience_temperature": 25.0429, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:20:07.562523+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.1, + "water_total": 189.0, + "average_temperature": 24.2667, + "experience_temperature": 25.0295, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:30:06.981503+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.3, + "humidity": 93.1, + "water_total": 189.0, + "average_temperature": 24.2667, + "experience_temperature": 24.7081, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:40:06.683691+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.3, + "humidity": 93.1, + "water_total": 189.0, + "average_temperature": 24.2667, + "experience_temperature": 24.7081, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T03:50:06.901789+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.3, + "humidity": 93.2, + "water_total": 193.0, + "average_temperature": 24.0667, + "experience_temperature": 24.5281, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:00:06.314078+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.2, + "water_total": 198.0, + "average_temperature": 24.0, + "experience_temperature": 24.7829, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:10:06.305664+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.3, + "water_total": 198.0, + "average_temperature": 24.0, + "experience_temperature": 24.8029, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:20:06.072579+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 202.0, + "average_temperature": 23.9333, + "experience_temperature": 24.7562, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:30:05.503193+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 207.0, + "average_temperature": 23.8333, + "experience_temperature": 24.6562, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:40:05.527490+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 93.7, + "water_total": 207.0, + "average_temperature": 23.8333, + "experience_temperature": 25.0376, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T04:50:05.673939+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.7, + "water_total": 207.0, + "average_temperature": 23.8667, + "experience_temperature": 24.7495, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:00:06.015990+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.8, + "water_total": 211.0, + "average_temperature": 23.8333, + "experience_temperature": 24.7362, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:10:05.520868+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.7, + "water_total": 211.0, + "average_temperature": 23.6333, + "experience_temperature": 24.5162, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:20:05.819530+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.7, + "water_total": 211.0, + "average_temperature": 23.6333, + "experience_temperature": 24.5162, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:30:06.257029+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 216.0, + "average_temperature": 23.6, + "experience_temperature": 24.5429, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:40:06.848151+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 216.0, + "average_temperature": 23.6, + "experience_temperature": 24.5429, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T05:50:06.512014+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.8, + "water_total": 225.0, + "average_temperature": 23.2333, + "experience_temperature": 24.1362, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:00:06.751646+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 93.8, + "water_total": 225.0, + "average_temperature": 23.2333, + "experience_temperature": 24.1362, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:10:06.864834+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.4, + "water_total": 230.0, + "average_temperature": 23.3667, + "experience_temperature": 24.3895, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:20:06.647181+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.3, + "water_total": 230.0, + "average_temperature": 23.3, + "experience_temperature": 24.3029, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:30:06.697211+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 94.6, + "water_total": 234.0, + "average_temperature": 23.5333, + "experience_temperature": 24.9176, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:40:06.884460+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 94.6, + "water_total": 234.0, + "average_temperature": 23.5333, + "experience_temperature": 24.9176, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T06:50:06.525811+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.7, + "water_total": 240.0, + "average_temperature": 23.8333, + "experience_temperature": 24.9162, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:00:07.158028+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.5, + "water_total": 240.0, + "average_temperature": 23.9667, + "experience_temperature": 25.0095, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:10:07.470752+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 94.5, + "water_total": 245.0, + "average_temperature": 24.1333, + "experience_temperature": 25.4976, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:20:06.255286+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 94.2, + "water_total": 245.0, + "average_temperature": 24.2333, + "experience_temperature": 25.5376, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:30:07.119611+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 94.0, + "water_total": 249.0, + "average_temperature": 24.4333, + "experience_temperature": 25.3762, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:40:05.969719+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.1, + "humidity": 93.6, + "water_total": 249.0, + "average_temperature": 24.6667, + "experience_temperature": 25.851, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T07:50:06.709063+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.9, + "water_total": 254.0, + "average_temperature": 24.8333, + "experience_temperature": 25.5562, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:00:07.565525+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.2, + "humidity": 92.9, + "water_total": 254.0, + "average_temperature": 24.8333, + "experience_temperature": 25.5562, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:10:07.959817+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 90.5, + "water_total": 258.0, + "average_temperature": 25.8333, + "experience_temperature": 25.4333, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:20:08.717327+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 88.7, + "water_total": 263.0, + "average_temperature": 26.2667, + "experience_temperature": 25.1852, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:30:07.062946+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 86.7, + "water_total": 263.0, + "average_temperature": 26.7667, + "experience_temperature": 24.6424, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:40:06.719559+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 84.6, + "water_total": 267.0, + "average_temperature": 27.0667, + "experience_temperature": 25.1652, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T08:50:06.505144+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 83.5, + "water_total": 279.0, + "average_temperature": 27.6333, + "experience_temperature": 25.1905, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:00:07.289111+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 80.9, + "water_total": 281.0, + "average_temperature": 28.0, + "experience_temperature": 25.0371, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:10:06.969803+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 79.7, + "water_total": 284.0, + "average_temperature": 28.5, + "experience_temperature": 25.6186, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:20:08.105688+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 77.8, + "water_total": 293.0, + "average_temperature": 28.9333, + "experience_temperature": 24.3862, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:30:07.546505+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 76.9, + "water_total": 293.0, + "average_temperature": 29.3667, + "experience_temperature": 24.961, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:40:06.808046+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 77.0, + "water_total": 309.0, + "average_temperature": 29.2667, + "experience_temperature": 24.5595, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T09:50:11.534928+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 75.0, + "water_total": 387.0, + "average_temperature": 29.3667, + "experience_temperature": 24.2595, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:00:08.168563+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.5, + "humidity": 76.2, + "water_total": 591.0, + "average_temperature": 29.7333, + "experience_temperature": 22.9376, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:10:09.131300+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 72.7, + "water_total": 743.0, + "average_temperature": 29.7667, + "experience_temperature": 22.9138, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:20:06.495711+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 72.2, + "water_total": 938.0, + "average_temperature": 29.7667, + "experience_temperature": 22.4924, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:30:06.708092+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 72.4, + "water_total": 1102.0, + "average_temperature": 30.4, + "experience_temperature": 24.13, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:40:08.135904+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 69.8, + "water_total": 1254.0, + "average_temperature": 30.2333, + "experience_temperature": 23.1219, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T10:50:07.165349+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 71.2, + "water_total": 1364.0, + "average_temperature": 30.1333, + "experience_temperature": 23.3019, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:00:06.932164+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 71.3, + "water_total": 1441.0, + "average_temperature": 29.9333, + "experience_temperature": 22.8005, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:10:06.859362+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 70.0, + "water_total": 1550.0, + "average_temperature": 30.6, + "experience_temperature": 23.2071, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:20:09.151724+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 71.1, + "water_total": 1640.0, + "average_temperature": 30.5, + "experience_temperature": 23.0057, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:30:07.277603+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 70.0, + "water_total": 1729.0, + "average_temperature": 30.8333, + "experience_temperature": 24.0833, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:40:07.099136+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 70.8, + "water_total": 1739.0, + "average_temperature": 30.8333, + "experience_temperature": 23.9219, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T11:50:05.747914+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 68.8, + "water_total": 1749.0, + "average_temperature": 31.1333, + "experience_temperature": 23.8219, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:00:06.073245+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 68.8, + "water_total": 1749.0, + "average_temperature": 31.1333, + "experience_temperature": 23.8219, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:10:08.586530+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 70.6, + "water_total": 1774.0, + "average_temperature": 30.8, + "experience_temperature": 23.2057, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:20:06.245510+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 69.9, + "water_total": 1788.0, + "average_temperature": 30.9333, + "experience_temperature": 23.5205, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:30:05.792939+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 67.5, + "water_total": 1801.0, + "average_temperature": 31.0667, + "experience_temperature": 23.8167, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:40:06.763145+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 67.3, + "water_total": 1812.0, + "average_temperature": 31.0, + "experience_temperature": 22.7457, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T12:50:06.041494+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 70.1, + "water_total": 1822.0, + "average_temperature": 30.6333, + "experience_temperature": 23.9033, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:00:05.955047+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.0, + "humidity": 67.6, + "water_total": 1836.0, + "average_temperature": 31.0333, + "experience_temperature": 24.1248, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:10:05.607142+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 66.9, + "water_total": 1846.0, + "average_temperature": 30.8, + "experience_temperature": 22.7871, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:20:08.494406+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 68.8, + "water_total": 1860.0, + "average_temperature": 30.6667, + "experience_temperature": 23.0338, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:30:06.959458+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 68.3, + "water_total": 1870.0, + "average_temperature": 31.2, + "experience_temperature": 23.4671, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:40:06.965772+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 67.1, + "water_total": 1885.0, + "average_temperature": 31.2, + "experience_temperature": 23.5486, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T13:50:06.582497+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 67.4, + "water_total": 1895.0, + "average_temperature": 31.1, + "experience_temperature": 22.8657, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T14:10:06.566303+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 69.5, + "water_total": 1981.0, + "average_temperature": 31.2333, + "experience_temperature": 23.419, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T14:20:06.311720+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 69.5, + "water_total": 1981.0, + "average_temperature": 31.2333, + "experience_temperature": 23.419, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T14:30:06.785528+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 69.4, + "water_total": 2138.0, + "average_temperature": 30.7333, + "experience_temperature": 23.5419, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T14:40:06.879760+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.5, + "humidity": 69.0, + "water_total": 2231.0, + "average_temperature": 31.1333, + "experience_temperature": 22.8976, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T14:50:06.054323+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 65.9, + "water_total": 2313.0, + "average_temperature": 31.0, + "experience_temperature": 22.4657, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T15:10:06.231124+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.2, + "humidity": 73.6, + "water_total": 2471.0, + "average_temperature": 30.9333, + "experience_temperature": 24.5819, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T15:20:07.286183+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 72.6, + "water_total": 2535.0, + "average_temperature": 30.9333, + "experience_temperature": 24.7033, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T15:30:06.380614+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 72.7, + "water_total": 2585.0, + "average_temperature": 30.9, + "experience_temperature": 24.69, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T15:40:09.512919+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 72.2, + "water_total": 2622.0, + "average_temperature": 30.8, + "experience_temperature": 23.8471, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T15:50:07.098793+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.5, + "humidity": 72.5, + "water_total": 2664.0, + "average_temperature": 30.7333, + "experience_temperature": 23.1976, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T16:10:06.588676+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 72.6, + "water_total": 2757.0, + "average_temperature": 30.6, + "experience_temperature": 23.7271, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T16:20:15.880136+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 72.9, + "water_total": 2801.0, + "average_temperature": 30.3667, + "experience_temperature": 23.2324, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T16:30:06.268645+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.4, + "humidity": 73.5, + "water_total": 2844.0, + "average_temperature": 30.1, + "experience_temperature": 23.0857, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T16:40:08.492932+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 73.7, + "water_total": 2886.0, + "average_temperature": 30.0, + "experience_temperature": 23.99, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T16:50:06.406878+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.3, + "humidity": 74.1, + "water_total": 2925.0, + "average_temperature": 29.9667, + "experience_temperature": 23.3938, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T17:10:07.518255+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.1, + "humidity": 73.4, + "water_total": 40.0, + "average_temperature": 29.7, + "experience_temperature": 23.63, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T17:20:06.495998+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 2.0, + "humidity": 73.9, + "water_total": 81.0, + "average_temperature": 29.5, + "experience_temperature": 23.8514, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T17:30:06.851401+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 73.7, + "water_total": 116.0, + "average_temperature": 29.4, + "experience_temperature": 24.3543, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T17:40:06.518735+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 73.6, + "water_total": 171.0, + "average_temperature": 29.2333, + "experience_temperature": 23.8462, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T17:50:06.096044+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 74.7, + "water_total": 212.0, + "average_temperature": 29.1, + "experience_temperature": 24.2543, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:00:06.321948+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 74.7, + "water_total": 212.0, + "average_temperature": 29.1, + "experience_temperature": 24.2543, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:10:06.482908+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 76.3, + "water_total": 295.0, + "average_temperature": 28.7333, + "experience_temperature": 23.8862, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:20:06.833833+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.9, + "humidity": 76.6, + "water_total": 342.0, + "average_temperature": 28.6, + "experience_temperature": 23.8129, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:30:06.644496+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 76.9, + "water_total": 383.0, + "average_temperature": 28.4667, + "experience_temperature": 24.7038, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:40:06.351441+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 78.7, + "water_total": 430.0, + "average_temperature": 28.1333, + "experience_temperature": 25.0519, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T18:50:05.957419+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 80.1, + "water_total": 471.0, + "average_temperature": 27.7333, + "experience_temperature": 25.2533, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:00:06.889316+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 80.1, + "water_total": 513.0, + "average_temperature": 27.7333, + "experience_temperature": 24.9319, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:10:05.869699+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 79.6, + "water_total": 554.0, + "average_temperature": 27.9333, + "experience_temperature": 25.0319, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:20:08.080562+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 79.8, + "water_total": 596.0, + "average_temperature": 27.9333, + "experience_temperature": 25.3933, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:30:06.583859+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 79.2, + "water_total": 643.0, + "average_temperature": 27.9333, + "experience_temperature": 24.309, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:40:06.245907+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 78.8, + "water_total": 678.0, + "average_temperature": 28.0, + "experience_temperature": 25.26, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T19:50:06.374385+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 79.2, + "water_total": 725.0, + "average_temperature": 27.9333, + "experience_temperature": 24.309, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:00:05.835824+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 79.2, + "water_total": 725.0, + "average_temperature": 27.9333, + "experience_temperature": 24.309, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:10:06.458795+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 80.3, + "water_total": 808.0, + "average_temperature": 27.7667, + "experience_temperature": 25.3267, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:20:06.561681+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 81.7, + "water_total": 849.0, + "average_temperature": 27.4333, + "experience_temperature": 24.6305, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:30:06.377248+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 82.3, + "water_total": 896.0, + "average_temperature": 27.3, + "experience_temperature": 25.26, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:40:06.604810+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 82.8, + "water_total": 939.0, + "average_temperature": 27.2333, + "experience_temperature": 24.9719, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T20:50:06.444640+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 82.9, + "water_total": 1001.0, + "average_temperature": 27.1667, + "experience_temperature": 24.9252, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:00:06.439364+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 83.8, + "water_total": 1064.0, + "average_temperature": 27.0667, + "experience_temperature": 24.3624, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:10:08.024800+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 1128.0, + "average_temperature": 26.8667, + "experience_temperature": 24.6838, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:20:05.823223+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 1128.0, + "average_temperature": 26.8667, + "experience_temperature": 24.6838, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:30:06.346821+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 86.2, + "water_total": 1185.0, + "average_temperature": 26.6, + "experience_temperature": 24.3757, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:40:06.410957+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 86.1, + "water_total": 1308.0, + "average_temperature": 26.6333, + "experience_temperature": 25.0319, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T21:50:06.955703+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 86.3, + "water_total": 1370.0, + "average_temperature": 26.6333, + "experience_temperature": 24.1076, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:00:06.433217+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.8, + "humidity": 86.3, + "water_total": 1370.0, + "average_temperature": 26.6333, + "experience_temperature": 24.1076, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:10:06.306467+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.5, + "humidity": 87.4, + "water_total": 1497.0, + "average_temperature": 26.4, + "experience_temperature": 25.0586, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:20:07.034456+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 87.8, + "water_total": 1558.0, + "average_temperature": 26.2333, + "experience_temperature": 24.6505, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:30:07.360504+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 88.2, + "water_total": 1618.0, + "average_temperature": 26.2, + "experience_temperature": 24.6971, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:40:07.043349+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 88.2, + "water_total": 1678.0, + "average_temperature": 26.1667, + "experience_temperature": 25.3067, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T22:50:06.655620+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 87.7, + "water_total": 1739.0, + "average_temperature": 26.4, + "experience_temperature": 25.44, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:00:07.758776+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 88.6, + "water_total": 1801.0, + "average_temperature": 26.5667, + "experience_temperature": 25.7867, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:10:06.153709+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 1861.0, + "average_temperature": 26.5, + "experience_temperature": 25.0571, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:20:05.725226+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 1861.0, + "average_temperature": 26.5, + "experience_temperature": 25.0571, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:30:07.797665+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.7, + "humidity": 88.2, + "water_total": 1988.0, + "average_temperature": 26.5333, + "experience_temperature": 24.709, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:40:06.378999+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 88.2, + "water_total": 2050.0, + "average_temperature": 26.6, + "experience_temperature": 25.74, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-29T23:50:07.418675+07:00", + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 88.2, + "water_total": 2050.0, + "average_temperature": 26.6, + "experience_temperature": 25.74, + "chill_factor": 3.2143 + }, + { + "timestamp": "2026-06-30T00:10:07.082112+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 88.6, + "water_total": 2236.0, + "average_temperature": 26.5, + "experience_temperature": 24.8771, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T00:20:08.812650+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 88.2, + "water_total": 2294.0, + "average_temperature": 26.5333, + "experience_temperature": 25.459, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T00:30:08.099293+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 88.0, + "water_total": 2357.0, + "average_temperature": 26.5667, + "experience_temperature": 25.4524, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T00:40:06.570688+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 2418.0, + "average_temperature": 26.4333, + "experience_temperature": 25.1048, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T00:50:06.977064+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 88.5, + "water_total": 2476.0, + "average_temperature": 26.2667, + "experience_temperature": 25.5667, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:00:05.826313+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 88.7, + "water_total": 2542.0, + "average_temperature": 26.1333, + "experience_temperature": 25.159, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:10:06.506954+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 88.7, + "water_total": 2600.0, + "average_temperature": 26.0, + "experience_temperature": 24.7114, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:20:06.023939+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 89.7, + "water_total": 2660.0, + "average_temperature": 25.7, + "experience_temperature": 24.6114, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:30:05.189932+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 90.3, + "water_total": 2724.0, + "average_temperature": 25.6333, + "experience_temperature": 24.979, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:40:05.367159+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 90.2, + "water_total": 2783.0, + "average_temperature": 25.8, + "experience_temperature": 25.44, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T01:50:05.393573+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 90.4, + "water_total": 2841.0, + "average_temperature": 25.7, + "experience_temperature": 25.0657, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:00:06.009438+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 90.8, + "water_total": 2902.0, + "average_temperature": 25.7, + "experience_temperature": 25.1457, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:10:05.384258+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.3, + "humidity": 90.9, + "water_total": 2964.0, + "average_temperature": 25.6333, + "experience_temperature": 25.7276, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:20:05.749916+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 91.2, + "water_total": 3029.0, + "average_temperature": 25.5667, + "experience_temperature": 25.0924, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:30:05.538378+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 91.2, + "water_total": 3029.0, + "average_temperature": 25.5667, + "experience_temperature": 25.0924, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:40:04.985862+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 91.5, + "water_total": 3148.0, + "average_temperature": 25.4, + "experience_temperature": 24.6714, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T02:50:06.286726+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 3213.0, + "average_temperature": 25.3, + "experience_temperature": 25.8086, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:00:06.113519+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 3273.0, + "average_temperature": 25.2667, + "experience_temperature": 25.8152, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:10:05.730981+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 91.7, + "water_total": 3335.0, + "average_temperature": 25.2333, + "experience_temperature": 25.8019, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:20:06.050442+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.1, + "humidity": 91.8, + "water_total": 3396.0, + "average_temperature": 25.2, + "experience_temperature": 26.1029, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:30:05.958675+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 3455.0, + "average_temperature": 25.2, + "experience_temperature": 25.8086, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:40:05.668380+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 3514.0, + "average_temperature": 25.2, + "experience_temperature": 25.8486, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T03:50:05.984332+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 3572.0, + "average_temperature": 25.1333, + "experience_temperature": 25.8019, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:00:05.784887+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 3572.0, + "average_temperature": 25.1333, + "experience_temperature": 25.8019, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:10:05.971942+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 3703.0, + "average_temperature": 25.0, + "experience_temperature": 25.7286, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:20:05.829615+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.1, + "humidity": 92.6, + "water_total": 3763.0, + "average_temperature": 24.9333, + "experience_temperature": 25.9962, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:30:06.184237+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.6, + "water_total": 3823.0, + "average_temperature": 24.9, + "experience_temperature": 25.6486, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:40:05.778539+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.1, + "humidity": 92.8, + "water_total": 3885.0, + "average_temperature": 24.7333, + "experience_temperature": 25.8362, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T04:50:05.288796+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.7, + "water_total": 3948.0, + "average_temperature": 24.7, + "experience_temperature": 25.4686, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:00:06.208871+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.2, + "humidity": 92.7, + "water_total": 3948.0, + "average_temperature": 24.7, + "experience_temperature": 25.4686, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:10:06.208136+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 91.6, + "water_total": 5162.0, + "average_temperature": 25.7, + "experience_temperature": 25.62, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:20:09.224265+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 90.7, + "water_total": 5292.0, + "average_temperature": 25.9333, + "experience_temperature": 25.0448, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:30:05.888300+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 90.7, + "water_total": 5292.0, + "average_temperature": 25.9333, + "experience_temperature": 25.0448, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:40:06.219954+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 89.6, + "water_total": 5600.0, + "average_temperature": 26.8333, + "experience_temperature": 26.3533, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T08:50:06.899172+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 5733.0, + "average_temperature": 27.0667, + "experience_temperature": 25.7381, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:00:10.448277+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 86.7, + "water_total": 5946.0, + "average_temperature": 27.7333, + "experience_temperature": 26.0448, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:10:08.927345+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 83.6, + "water_total": 6136.0, + "average_temperature": 28.2333, + "experience_temperature": 25.9248, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:20:06.789636+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 80.8, + "water_total": 6220.0, + "average_temperature": 28.7333, + "experience_temperature": 24.9219, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:30:06.532979+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 77.8, + "water_total": 6248.0, + "average_temperature": 28.9333, + "experience_temperature": 24.5219, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:40:10.442383+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 75.5, + "water_total": 6395.0, + "average_temperature": 29.1667, + "experience_temperature": 24.2952, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T09:50:07.005092+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 71.7, + "water_total": 6605.0, + "average_temperature": 29.4, + "experience_temperature": 23.7686, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:00:07.041223+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 71.7, + "water_total": 6605.0, + "average_temperature": 29.4, + "experience_temperature": 23.7686, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:10:06.727024+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 69.1, + "water_total": 7009.0, + "average_temperature": 30.1333, + "experience_temperature": 22.4105, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:20:06.882527+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.1, + "humidity": 66.8, + "water_total": 7214.0, + "average_temperature": 30.2333, + "experience_temperature": 22.9933, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:30:09.303788+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 68.3, + "water_total": 7245.0, + "average_temperature": 30.2667, + "experience_temperature": 22.6981, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:40:08.369593+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 66.1, + "water_total": 7251.0, + "average_temperature": 30.8667, + "experience_temperature": 22.5438, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T10:50:06.503114+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 67.3, + "water_total": 7322.0, + "average_temperature": 30.8333, + "experience_temperature": 23.0648, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:00:07.500340+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 64.8, + "water_total": 7407.0, + "average_temperature": 30.9, + "experience_temperature": 22.3171, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:10:08.042307+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 66.9, + "water_total": 7512.0, + "average_temperature": 30.5333, + "experience_temperature": 22.999, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:20:06.919541+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 65.4, + "water_total": 7612.0, + "average_temperature": 30.5333, + "experience_temperature": 22.699, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:30:07.004964+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 63.5, + "water_total": 7705.0, + "average_temperature": 30.9667, + "experience_temperature": 22.7524, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:40:07.931749+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 64.7, + "water_total": 7799.0, + "average_temperature": 30.8667, + "experience_temperature": 22.5781, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T11:50:08.368108+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 64.2, + "water_total": 7892.0, + "average_temperature": 30.8, + "experience_temperature": 22.7257, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:00:06.948417+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 65.5, + "water_total": 7991.0, + "average_temperature": 31.2667, + "experience_temperature": 23.1381, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:10:08.950809+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 66.8, + "water_total": 8063.0, + "average_temperature": 30.9333, + "experience_temperature": 23.0648, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:20:06.918764+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.1, + "humidity": 66.9, + "water_total": 8174.0, + "average_temperature": 30.7667, + "experience_temperature": 23.5467, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:30:07.258154+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 64.8, + "water_total": 8269.0, + "average_temperature": 30.9333, + "experience_temperature": 22.979, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:40:06.820505+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 64.4, + "water_total": 8362.0, + "average_temperature": 30.8667, + "experience_temperature": 22.8324, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T12:50:06.971809+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 66.1, + "water_total": 8456.0, + "average_temperature": 30.8, + "experience_temperature": 23.1057, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:00:05.994454+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 66.5, + "water_total": 8553.0, + "average_temperature": 30.5, + "experience_temperature": 22.2571, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:10:06.986286+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 65.1, + "water_total": 8645.0, + "average_temperature": 31.2333, + "experience_temperature": 23.0248, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:20:06.003365+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 66.2, + "water_total": 8730.0, + "average_temperature": 31.2, + "experience_temperature": 23.5257, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:30:07.247017+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 66.7, + "water_total": 8829.0, + "average_temperature": 30.9333, + "experience_temperature": 22.7305, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:40:07.980149+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.5, + "humidity": 67.4, + "water_total": 8921.0, + "average_temperature": 30.7333, + "experience_temperature": 22.3562, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T13:50:06.313013+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 69.0, + "water_total": 9023.0, + "average_temperature": 30.8, + "experience_temperature": 23.3714, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T14:10:06.057231+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 65.8, + "water_total": 9105.0, + "average_temperature": 30.9333, + "experience_temperature": 23.179, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T14:20:07.255190+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 66.5, + "water_total": 9114.0, + "average_temperature": 30.7333, + "experience_temperature": 23.119, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T14:30:08.338038+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 62.7, + "water_total": 9119.0, + "average_temperature": 30.9333, + "experience_temperature": 21.9305, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T14:40:06.632131+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 65.1, + "water_total": 9124.0, + "average_temperature": 30.9333, + "experience_temperature": 23.039, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T14:50:06.255614+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 66.1, + "water_total": 9133.0, + "average_temperature": 30.5, + "experience_temperature": 22.1771, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T15:10:09.219415+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 65.6, + "water_total": 9142.0, + "average_temperature": 31.2, + "experience_temperature": 23.0914, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T15:20:06.957400+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 70.6, + "water_total": 9147.0, + "average_temperature": 30.4, + "experience_temperature": 23.6057, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T15:30:07.233475+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 72.3, + "water_total": 9152.0, + "average_temperature": 30.1, + "experience_temperature": 23.3314, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T15:40:08.127505+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 72.0, + "water_total": 9157.0, + "average_temperature": 30.4, + "experience_temperature": 23.2571, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T15:50:06.585799+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.4, + "humidity": 72.0, + "water_total": 9157.0, + "average_temperature": 30.4, + "experience_temperature": 23.2571, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T16:10:07.034245+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.1, + "humidity": 71.7, + "water_total": 9171.0, + "average_temperature": 30.2333, + "experience_temperature": 23.9733, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T16:20:06.686151+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.1, + "humidity": 72.2, + "water_total": 9176.0, + "average_temperature": 30.2, + "experience_temperature": 24.04, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T16:30:06.375910+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 72.6, + "water_total": 9180.0, + "average_temperature": 30.1, + "experience_temperature": 23.7057, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T16:40:06.487634+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.3, + "humidity": 73.5, + "water_total": 9185.0, + "average_temperature": 29.8, + "experience_temperature": 23.2714, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T16:50:07.991161+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 2.2, + "humidity": 74.1, + "water_total": 9189.0, + "average_temperature": 29.5667, + "experience_temperature": 23.4724, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T17:10:09.433346+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 73.5, + "water_total": 4.0, + "average_temperature": 29.2333, + "experience_temperature": 23.9619, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T17:20:06.899666+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 9.0, + "average_temperature": 29.0333, + "experience_temperature": 23.6619, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T17:30:08.327512+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 13.0, + "average_temperature": 28.7667, + "experience_temperature": 23.3952, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T17:40:06.676447+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 18.0, + "average_temperature": 28.6, + "experience_temperature": 23.2286, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T17:50:06.937687+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.9, + "humidity": 73.3, + "water_total": 23.0, + "average_temperature": 28.4333, + "experience_temperature": 23.1219, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:00:07.869814+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 74.7, + "water_total": 27.0, + "average_temperature": 28.1333, + "experience_temperature": 24.0448, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:10:06.943258+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 76.1, + "water_total": 32.0, + "average_temperature": 27.9, + "experience_temperature": 23.7771, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:20:07.559063+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 76.3, + "water_total": 36.0, + "average_temperature": 27.8667, + "experience_temperature": 23.7838, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:30:06.724519+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 76.3, + "water_total": 41.0, + "average_temperature": 27.8333, + "experience_temperature": 23.7505, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:40:06.831646+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 77.0, + "water_total": 45.0, + "average_temperature": 27.7333, + "experience_temperature": 24.1048, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T18:50:06.747990+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 79.3, + "water_total": 45.0, + "average_temperature": 27.3667, + "experience_temperature": 24.1981, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:00:07.594212+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 78.9, + "water_total": 54.0, + "average_temperature": 27.2333, + "experience_temperature": 24.299, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:10:06.520805+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 79.2, + "water_total": 54.0, + "average_temperature": 27.2333, + "experience_temperature": 24.6733, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:20:07.257748+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 79.4, + "water_total": 59.0, + "average_temperature": 27.1333, + "experience_temperature": 23.9848, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:30:06.508013+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 79.4, + "water_total": 59.0, + "average_temperature": 27.1333, + "experience_temperature": 23.9848, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:40:07.324061+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.7, + "water_total": 67.0, + "average_temperature": 26.7, + "experience_temperature": 24.5257, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T19:50:06.452835+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.3, + "water_total": 72.0, + "average_temperature": 26.7333, + "experience_temperature": 24.479, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:00:06.808713+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.3, + "water_total": 72.0, + "average_temperature": 26.7333, + "experience_temperature": 24.479, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:10:06.776406+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 79.3, + "water_total": 76.0, + "average_temperature": 27.2333, + "experience_temperature": 24.0648, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:20:06.620489+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 80.3, + "water_total": 81.0, + "average_temperature": 27.1333, + "experience_temperature": 24.479, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:30:07.553098+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 81.7, + "water_total": 85.0, + "average_temperature": 26.9333, + "experience_temperature": 24.559, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:40:06.839993+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 82.1, + "water_total": 90.0, + "average_temperature": 26.9333, + "experience_temperature": 24.3248, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T20:50:06.944317+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 82.0, + "water_total": 94.0, + "average_temperature": 26.9333, + "experience_temperature": 24.3048, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:00:06.779015+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 82.1, + "water_total": 99.0, + "average_temperature": 27.0333, + "experience_temperature": 24.1105, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:10:06.863149+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.3, + "water_total": 99.0, + "average_temperature": 27.0333, + "experience_temperature": 24.779, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:20:06.914130+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 82.4, + "water_total": 104.0, + "average_temperature": 26.9333, + "experience_temperature": 24.0705, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:30:07.516227+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.5, + "water_total": 108.0, + "average_temperature": 27.0, + "experience_temperature": 24.7857, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:40:06.606848+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 82.6, + "water_total": 113.0, + "average_temperature": 27.0333, + "experience_temperature": 24.839, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T21:50:06.737784+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 82.8, + "water_total": 117.0, + "average_temperature": 27.0333, + "experience_temperature": 24.5648, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:00:06.857269+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 84.2, + "water_total": 117.0, + "average_temperature": 26.6, + "experience_temperature": 24.4114, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:10:06.421868+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 85.5, + "water_total": 121.0, + "average_temperature": 26.4667, + "experience_temperature": 25.1667, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:20:06.498258+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 86.0, + "water_total": 126.0, + "average_temperature": 26.2667, + "experience_temperature": 24.7524, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:30:08.583040+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 85.4, + "water_total": 126.0, + "average_temperature": 26.2667, + "experience_temperature": 24.9467, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:40:06.926855+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.4, + "humidity": 84.2, + "water_total": 130.0, + "average_temperature": 26.3, + "experience_temperature": 24.74, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T22:50:07.407820+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 83.0, + "water_total": 135.0, + "average_temperature": 26.2667, + "experience_temperature": 24.1524, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:00:06.814102+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 81.6, + "water_total": 139.0, + "average_temperature": 26.2333, + "experience_temperature": 23.839, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:10:05.442772+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 81.8, + "water_total": 139.0, + "average_temperature": 26.2333, + "experience_temperature": 23.879, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:20:05.115782+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.7, + "humidity": 82.4, + "water_total": 143.0, + "average_temperature": 26.1333, + "experience_temperature": 23.2705, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:30:06.496732+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.5, + "humidity": 83.5, + "water_total": 148.0, + "average_temperature": 26.0, + "experience_temperature": 23.9857, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:40:06.086390+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 148.0, + "average_temperature": 25.9, + "experience_temperature": 23.7314, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-06-30T23:50:05.306855+07:00", + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 148.0, + "average_temperature": 25.9, + "experience_temperature": 23.7314, + "chill_factor": 3.1429 + }, + { + "timestamp": "2026-07-01T00:00:06.420455+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.8, + "humidity": 83.4, + "water_total": 156.0, + "average_temperature": 25.5333, + "experience_temperature": 22.6848, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T00:10:06.674401+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 83.4, + "water_total": 157.0, + "average_temperature": 25.4333, + "experience_temperature": 23.5062, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T00:20:06.023701+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 83.3, + "water_total": 162.0, + "average_temperature": 25.2333, + "experience_temperature": 24.2076, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T00:30:08.303779+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 84.6, + "water_total": 168.0, + "average_temperature": 25.1667, + "experience_temperature": 24.401, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T00:40:05.833151+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 84.6, + "water_total": 168.0, + "average_temperature": 25.1667, + "experience_temperature": 24.401, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T00:50:05.447216+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 86.2, + "water_total": 172.0, + "average_temperature": 24.9, + "experience_temperature": 24.7614, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:00:06.010454+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 86.2, + "water_total": 172.0, + "average_temperature": 24.9, + "experience_temperature": 24.7614, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:10:06.125659+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 87.0, + "water_total": 177.0, + "average_temperature": 24.5333, + "experience_temperature": 24.2476, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:20:05.489331+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 86.7, + "water_total": 182.0, + "average_temperature": 24.3, + "experience_temperature": 24.2614, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:30:05.552795+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.3, + "water_total": 182.0, + "average_temperature": 24.1667, + "experience_temperature": 23.741, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:40:05.779142+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 188.0, + "average_temperature": 24.0, + "experience_temperature": 23.5343, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T01:50:05.654112+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 192.0, + "average_temperature": 23.9667, + "experience_temperature": 23.501, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:00:05.457745+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 192.0, + "average_temperature": 23.9667, + "experience_temperature": 23.501, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:10:05.188073+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.1, + "water_total": 198.0, + "average_temperature": 23.6667, + "experience_temperature": 23.201, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:20:05.713650+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.3, + "water_total": 202.0, + "average_temperature": 23.6333, + "experience_temperature": 23.2076, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:30:06.179435+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.4, + "water_total": 202.0, + "average_temperature": 23.5, + "experience_temperature": 23.0943, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:40:06.069729+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.5, + "water_total": 207.0, + "average_temperature": 23.4333, + "experience_temperature": 23.0476, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T02:50:07.717782+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 207.0, + "average_temperature": 23.2, + "experience_temperature": 22.8543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:00:05.688231+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 207.0, + "average_temperature": 23.2, + "experience_temperature": 22.8543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:10:05.190630+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 86.9, + "water_total": 213.0, + "average_temperature": 23.1, + "experience_temperature": 23.1014, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:20:06.197324+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 87.9, + "water_total": 219.0, + "average_temperature": 22.8333, + "experience_temperature": 22.7276, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:30:05.941056+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.1, + "water_total": 224.0, + "average_temperature": 22.9, + "experience_temperature": 22.8343, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:40:06.167994+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.0, + "humidity": 88.2, + "water_total": 233.0, + "average_temperature": 22.8, + "experience_temperature": 23.3686, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T03:50:05.457075+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.2, + "water_total": 233.0, + "average_temperature": 22.7, + "experience_temperature": 22.6543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:00:05.397290+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.2, + "water_total": 233.0, + "average_temperature": 22.7, + "experience_temperature": 22.6543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:10:06.077911+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 88.4, + "water_total": 248.0, + "average_temperature": 22.5667, + "experience_temperature": 22.8681, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:20:05.760182+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 88.6, + "water_total": 260.0, + "average_temperature": 22.4667, + "experience_temperature": 22.8081, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:30:06.473358+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.7, + "water_total": 269.0, + "average_temperature": 22.4, + "experience_temperature": 22.4543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:40:05.950408+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 88.9, + "water_total": 280.0, + "average_temperature": 22.3, + "experience_temperature": 22.7014, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T04:50:05.867597+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.3, + "humidity": 89.0, + "water_total": 294.0, + "average_temperature": 22.2333, + "experience_temperature": 22.0405, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:00:06.071333+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 303.0, + "average_temperature": 22.1667, + "experience_temperature": 22.301, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:10:05.511267+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 319.0, + "average_temperature": 22.1333, + "experience_temperature": 22.2476, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:20:05.737689+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 329.0, + "average_temperature": 22.0667, + "experience_temperature": 22.161, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:30:06.334629+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 88.8, + "water_total": 339.0, + "average_temperature": 21.9333, + "experience_temperature": 22.0076, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:40:05.845377+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 89.5, + "water_total": 348.0, + "average_temperature": 21.9333, + "experience_temperature": 22.4548, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T05:50:05.246596+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 357.0, + "average_temperature": 21.9333, + "experience_temperature": 22.1876, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:00:06.477174+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 357.0, + "average_temperature": 21.9333, + "experience_temperature": 22.1876, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:10:05.991166+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 380.0, + "average_temperature": 21.6667, + "experience_temperature": 22.001, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:20:05.791868+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 90.3, + "water_total": 390.0, + "average_temperature": 21.6667, + "experience_temperature": 22.3481, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:30:05.686610+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 90.6, + "water_total": 400.0, + "average_temperature": 21.7, + "experience_temperature": 22.1343, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:40:06.631917+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 410.0, + "average_temperature": 21.8, + "experience_temperature": 22.2543, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T06:50:05.902868+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 90.7, + "water_total": 426.0, + "average_temperature": 22.0667, + "experience_temperature": 22.8281, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:00:06.791966+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 90.5, + "water_total": 437.0, + "average_temperature": 22.3, + "experience_temperature": 22.7143, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:10:07.167600+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 90.2, + "water_total": 446.0, + "average_temperature": 22.5333, + "experience_temperature": 23.1948, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:20:05.823700+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 456.0, + "average_temperature": 22.8, + "experience_temperature": 22.9943, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:30:06.052347+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 88.6, + "water_total": 470.0, + "average_temperature": 23.2667, + "experience_temperature": 23.6081, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:40:06.139415+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.1, + "humidity": 87.5, + "water_total": 482.0, + "average_temperature": 23.7, + "experience_temperature": 23.8214, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T07:50:06.264103+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.2, + "water_total": 491.0, + "average_temperature": 24.2667, + "experience_temperature": 23.821, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:00:05.953745+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 86.2, + "water_total": 491.0, + "average_temperature": 24.2667, + "experience_temperature": 23.821, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:10:07.896266+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.2, + "humidity": 84.4, + "water_total": 507.0, + "average_temperature": 24.8333, + "experience_temperature": 24.0276, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:20:06.350598+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 81.0, + "water_total": 528.0, + "average_temperature": 26.0, + "experience_temperature": 23.9, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:30:06.044323+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 78.9, + "water_total": 543.0, + "average_temperature": 26.5, + "experience_temperature": 23.6729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:40:06.284067+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 77.4, + "water_total": 554.0, + "average_temperature": 27.1333, + "experience_temperature": 23.699, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T08:50:06.905170+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 76.3, + "water_total": 569.0, + "average_temperature": 27.6, + "experience_temperature": 24.2529, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:00:08.283063+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 74.4, + "water_total": 608.0, + "average_temperature": 28.2, + "experience_temperature": 24.4729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:10:06.204584+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.8, + "humidity": 72.9, + "water_total": 660.0, + "average_temperature": 28.6333, + "experience_temperature": 23.6848, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:20:06.542389+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.9, + "humidity": 70.3, + "water_total": 775.0, + "average_temperature": 28.7667, + "experience_temperature": 22.991, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:30:06.144811+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.9, + "humidity": 71.1, + "water_total": 999.0, + "average_temperature": 29.2333, + "experience_temperature": 23.6176, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:40:06.462782+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 68.3, + "water_total": 1188.0, + "average_temperature": 29.6, + "experience_temperature": 22.1957, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T09:50:06.644411+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 66.8, + "water_total": 1380.0, + "average_temperature": 29.8333, + "experience_temperature": 21.8219, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:00:09.072692+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.2, + "water_total": 1537.0, + "average_temperature": 29.8, + "experience_temperature": 21.3757, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:10:06.698948+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 61.4, + "water_total": 1623.0, + "average_temperature": 30.1667, + "experience_temperature": 21.6895, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:20:06.750805+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 65.1, + "water_total": 1696.0, + "average_temperature": 30.4333, + "experience_temperature": 22.389, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:30:10.795912+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 64.2, + "water_total": 1726.0, + "average_temperature": 30.4333, + "experience_temperature": 22.5162, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:40:08.918046+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.5, + "water_total": 1731.0, + "average_temperature": 30.2333, + "experience_temperature": 21.869, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T10:50:06.500101+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 64.0, + "water_total": 1740.0, + "average_temperature": 30.9333, + "experience_temperature": 22.669, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:00:09.098741+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 63.1, + "water_total": 1745.0, + "average_temperature": 30.5667, + "experience_temperature": 21.8152, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:10:05.884733+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 63.1, + "water_total": 1750.0, + "average_temperature": 30.7333, + "experience_temperature": 22.5962, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:20:06.713810+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 62.4, + "water_total": 1754.0, + "average_temperature": 30.4, + "experience_temperature": 21.8157, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:30:09.701598+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 62.4, + "water_total": 1754.0, + "average_temperature": 30.4, + "experience_temperature": 21.8157, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:40:06.973045+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 63.9, + "water_total": 1764.0, + "average_temperature": 30.3333, + "experience_temperature": 22.3562, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T11:50:06.691150+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 60.4, + "water_total": 1773.0, + "average_temperature": 30.7333, + "experience_temperature": 22.0562, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:00:05.888671+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 61.7, + "water_total": 1777.0, + "average_temperature": 30.5, + "experience_temperature": 22.39, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:10:07.381084+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 60.2, + "water_total": 1782.0, + "average_temperature": 30.6667, + "experience_temperature": 21.3352, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:20:05.891408+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 61.8, + "water_total": 1787.0, + "average_temperature": 30.6333, + "experience_temperature": 22.2362, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:30:06.869342+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 60.6, + "water_total": 1792.0, + "average_temperature": 31.1333, + "experience_temperature": 22.8033, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:40:06.747901+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 62.7, + "water_total": 1796.0, + "average_temperature": 30.8333, + "experience_temperature": 22.0019, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T12:50:06.289275+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 62.8, + "water_total": 1801.0, + "average_temperature": 30.6333, + "experience_temperature": 22.129, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:00:06.240749+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 62.1, + "water_total": 1806.0, + "average_temperature": 30.7333, + "experience_temperature": 22.089, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:10:07.498298+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 61.4, + "water_total": 1814.0, + "average_temperature": 30.9667, + "experience_temperature": 22.1824, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:20:06.573351+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 61.6, + "water_total": 1815.0, + "average_temperature": 30.7333, + "experience_temperature": 22.2962, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:30:07.005164+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 60.8, + "water_total": 1825.0, + "average_temperature": 30.5667, + "experience_temperature": 21.6624, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:40:05.969197+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 61.0, + "water_total": 1825.0, + "average_temperature": 31.0, + "experience_temperature": 22.4429, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T13:50:05.739260+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 59.9, + "water_total": 1830.0, + "average_temperature": 31.1, + "experience_temperature": 21.7086, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T14:10:06.129936+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 65.0, + "water_total": 1840.0, + "average_temperature": 30.5667, + "experience_temperature": 22.1952, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T14:20:08.244911+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 65.0, + "water_total": 1840.0, + "average_temperature": 30.5667, + "experience_temperature": 22.1952, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T14:30:10.561415+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 61.1, + "water_total": 1849.0, + "average_temperature": 30.7333, + "experience_temperature": 22.1962, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T14:40:09.113830+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 63.3, + "water_total": 1854.0, + "average_temperature": 31.1667, + "experience_temperature": 23.0695, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T14:50:06.161703+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 63.3, + "water_total": 1854.0, + "average_temperature": 31.1667, + "experience_temperature": 23.0695, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T15:10:05.729521+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.4, + "water_total": 1868.0, + "average_temperature": 30.7667, + "experience_temperature": 22.3824, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T15:20:05.707436+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.2, + "water_total": 1873.0, + "average_temperature": 30.8667, + "experience_temperature": 22.4424, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T15:30:08.596039+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 63.5, + "water_total": 1878.0, + "average_temperature": 30.3667, + "experience_temperature": 22.6167, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T15:40:06.498568+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 63.0, + "water_total": 1878.0, + "average_temperature": 30.4333, + "experience_temperature": 21.6619, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T15:50:05.539804+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 64.7, + "water_total": 1883.0, + "average_temperature": 30.7333, + "experience_temperature": 22.3019, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T16:10:06.150848+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 64.7, + "water_total": 1883.0, + "average_temperature": 30.7333, + "experience_temperature": 22.3019, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T16:20:07.067529+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.5, + "water_total": 1892.0, + "average_temperature": 30.6, + "experience_temperature": 22.2357, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T16:30:05.635104+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.3, + "humidity": 63.7, + "water_total": 1897.0, + "average_temperature": 30.4, + "experience_temperature": 22.0757, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T16:40:05.806931+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 62.9, + "water_total": 1902.0, + "average_temperature": 30.3667, + "experience_temperature": 22.4967, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T16:50:05.931098+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.4, + "humidity": 62.8, + "water_total": 1906.0, + "average_temperature": 30.4, + "experience_temperature": 21.5886, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T17:10:06.252649+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.2, + "humidity": 70.2, + "water_total": 0.0, + "average_temperature": 29.3333, + "experience_temperature": 22.6162, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T17:20:06.332494+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 71.3, + "water_total": 4.0, + "average_temperature": 29.2333, + "experience_temperature": 23.0433, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T17:30:06.042522+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.8, + "humidity": 72.4, + "water_total": 9.0, + "average_temperature": 29.0, + "experience_temperature": 23.9514, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T17:40:06.048332+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.0, + "humidity": 72.8, + "water_total": 14.0, + "average_temperature": 28.8333, + "experience_temperature": 23.2505, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T17:50:05.140421+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.9, + "humidity": 73.6, + "water_total": 14.0, + "average_temperature": 28.6, + "experience_temperature": 23.4843, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:00:06.316358+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 19.0, + "average_temperature": 28.3333, + "experience_temperature": 22.7633, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:10:06.307438+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 75.2, + "water_total": 24.0, + "average_temperature": 28.1333, + "experience_temperature": 24.5662, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:20:06.705704+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 75.7, + "water_total": 29.0, + "average_temperature": 28.0, + "experience_temperature": 24.2257, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:30:07.376070+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 76.4, + "water_total": 29.0, + "average_temperature": 27.8333, + "experience_temperature": 24.5062, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:40:06.158309+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 76.4, + "water_total": 29.0, + "average_temperature": 27.8333, + "experience_temperature": 24.5062, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T18:50:06.749322+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.7, + "humidity": 77.8, + "water_total": 39.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9052, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:00:07.067338+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.7, + "humidity": 78.0, + "water_total": 39.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9452, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:10:08.348855+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 78.8, + "water_total": 43.0, + "average_temperature": 27.3667, + "experience_temperature": 24.2124, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:20:11.780718+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 79.4, + "water_total": 48.0, + "average_temperature": 27.2, + "experience_temperature": 24.4729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:30:07.187233+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 79.4, + "water_total": 48.0, + "average_temperature": 27.2, + "experience_temperature": 24.4729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:40:07.585523+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.7, + "humidity": 79.4, + "water_total": 53.0, + "average_temperature": 27.2333, + "experience_temperature": 23.8919, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T19:50:06.009343+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 79.5, + "water_total": 58.0, + "average_temperature": 27.3333, + "experience_temperature": 24.319, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:00:05.888324+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 79.5, + "water_total": 58.0, + "average_temperature": 27.3333, + "experience_temperature": 24.319, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:10:06.477502+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 74.4, + "water_total": 58.0, + "average_temperature": 28.2, + "experience_temperature": 24.4729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:20:06.582581+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 74.4, + "water_total": 64.0, + "average_temperature": 28.2, + "experience_temperature": 24.4729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:30:06.795934+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 80.8, + "water_total": 69.0, + "average_temperature": 27.0333, + "experience_temperature": 24.279, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:40:06.233017+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 82.1, + "water_total": 70.0, + "average_temperature": 26.7, + "experience_temperature": 24.82, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T20:50:07.174410+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 82.9, + "water_total": 75.0, + "average_temperature": 26.9333, + "experience_temperature": 24.599, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:00:06.932045+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 83.2, + "water_total": 75.0, + "average_temperature": 26.7667, + "experience_temperature": 25.1067, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:10:06.940006+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 84.0, + "water_total": 80.0, + "average_temperature": 26.6333, + "experience_temperature": 24.519, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:20:08.163159+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 83.9, + "water_total": 84.0, + "average_temperature": 26.5, + "experience_temperature": 24.6729, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:30:06.838199+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 84.5, + "water_total": 84.0, + "average_temperature": 26.4333, + "experience_temperature": 24.7262, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:40:06.317387+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.7, + "humidity": 84.8, + "water_total": 88.0, + "average_temperature": 26.2333, + "experience_temperature": 23.9719, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T21:50:06.633155+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 84.3, + "water_total": 88.0, + "average_temperature": 26.2333, + "experience_temperature": 24.4862, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:00:07.927980+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 85.0, + "water_total": 93.0, + "average_temperature": 26.1333, + "experience_temperature": 24.5262, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:10:06.660041+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 85.1, + "water_total": 95.0, + "average_temperature": 25.9333, + "experience_temperature": 24.3462, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:20:06.310625+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 85.1, + "water_total": 95.0, + "average_temperature": 25.9333, + "experience_temperature": 24.3462, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:30:07.112651+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 86.9, + "water_total": 99.0, + "average_temperature": 25.6333, + "experience_temperature": 24.099, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:40:07.745133+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 87.3, + "water_total": 100.0, + "average_temperature": 25.5, + "experience_temperature": 24.0457, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T22:50:07.986930+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 88.0, + "water_total": 104.0, + "average_temperature": 25.5333, + "experience_temperature": 24.5262, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:00:06.881037+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.6, + "humidity": 87.9, + "water_total": 105.0, + "average_temperature": 25.6333, + "experience_temperature": 24.299, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:10:06.068176+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 87.8, + "water_total": 110.0, + "average_temperature": 25.6333, + "experience_temperature": 24.8933, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:20:06.738630+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 87.3, + "water_total": 111.0, + "average_temperature": 25.6667, + "experience_temperature": 24.8267, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:30:06.247655+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.4, + "humidity": 87.3, + "water_total": 111.0, + "average_temperature": 25.6667, + "experience_temperature": 24.8267, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:40:06.958262+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 86.6, + "water_total": 117.0, + "average_temperature": 25.6, + "experience_temperature": 24.3129, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-01T23:50:08.103427+07:00", + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 123.0, + "average_temperature": 25.5, + "experience_temperature": 24.2529, + "chill_factor": 3.0714 + }, + { + "timestamp": "2026-07-02T00:00:06.833517+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 123.0, + "average_temperature": 25.5, + "experience_temperature": 24.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T00:10:06.932837+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 87.5, + "water_total": 126.0, + "average_temperature": 25.2333, + "experience_temperature": 24.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T00:20:07.032744+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 87.7, + "water_total": 132.0, + "average_temperature": 25.1333, + "experience_temperature": 23.8733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T00:30:06.990510+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 87.7, + "water_total": 132.0, + "average_temperature": 25.1333, + "experience_temperature": 23.8733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T00:40:06.190116+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.4, + "water_total": 132.0, + "average_temperature": 25.0667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T00:50:06.515903+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.1, + "water_total": 138.0, + "average_temperature": 25.0333, + "experience_temperature": 24.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:00:07.085152+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 86.9, + "water_total": 144.0, + "average_temperature": 25.0667, + "experience_temperature": 25.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:10:06.724075+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 83.9, + "water_total": 144.0, + "average_temperature": 26.5333, + "experience_temperature": 24.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:20:06.198085+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.4, + "water_total": 158.0, + "average_temperature": 24.9333, + "experience_temperature": 24.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:30:06.097951+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 88.0, + "water_total": 163.0, + "average_temperature": 24.9, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:40:06.469890+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 88.6, + "water_total": 169.0, + "average_temperature": 24.8, + "experience_temperature": 24.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T01:50:06.796369+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 89.0, + "water_total": 169.0, + "average_temperature": 24.7333, + "experience_temperature": 25.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:00:06.914956+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 174.0, + "average_temperature": 24.6667, + "experience_temperature": 24.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:10:07.535406+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 89.5, + "water_total": 177.0, + "average_temperature": 24.6, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:20:06.464159+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 89.8, + "water_total": 181.0, + "average_temperature": 24.5, + "experience_temperature": 25.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:30:07.348436+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 181.0, + "average_temperature": 24.4, + "experience_temperature": 24.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:40:06.923488+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.0, + "humidity": 90.1, + "water_total": 188.0, + "average_temperature": 24.3333, + "experience_temperature": 25.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T02:50:06.088616+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.4, + "water_total": 195.0, + "average_temperature": 24.3, + "experience_temperature": 24.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:00:06.405017+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.6, + "water_total": 201.0, + "average_temperature": 24.2, + "experience_temperature": 24.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:10:06.917185+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.8, + "water_total": 201.0, + "average_temperature": 24.1667, + "experience_temperature": 24.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:20:06.010726+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 90.8, + "water_total": 206.0, + "average_temperature": 24.1667, + "experience_temperature": 25.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:30:06.493463+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 213.0, + "average_temperature": 24.0667, + "experience_temperature": 24.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:40:06.323063+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 90.3, + "water_total": 216.0, + "average_temperature": 23.9667, + "experience_temperature": 24.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T03:50:06.502213+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 224.0, + "average_temperature": 23.8333, + "experience_temperature": 24.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:00:06.764988+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 89.6, + "water_total": 229.0, + "average_temperature": 23.7667, + "experience_temperature": 24.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:10:06.515217+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 88.8, + "water_total": 229.0, + "average_temperature": 23.6333, + "experience_temperature": 23.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:20:07.537922+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.8, + "water_total": 236.0, + "average_temperature": 23.5333, + "experience_temperature": 23.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:30:06.451279+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 86.8, + "water_total": 243.0, + "average_temperature": 23.4333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:40:07.679712+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 85.8, + "water_total": 243.0, + "average_temperature": 23.4333, + "experience_temperature": 23.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T04:50:06.415459+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 85.3, + "water_total": 248.0, + "average_temperature": 23.4333, + "experience_temperature": 22.8933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:00:09.005591+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 85.3, + "water_total": 254.0, + "average_temperature": 23.4333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:10:06.153957+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 85.7, + "water_total": 260.0, + "average_temperature": 23.4333, + "experience_temperature": 22.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:20:06.747475+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 86.2, + "water_total": 264.0, + "average_temperature": 23.2667, + "experience_temperature": 22.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:30:06.219888+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 272.0, + "average_temperature": 23.2, + "experience_temperature": 22.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:40:07.901497+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.0, + "water_total": 277.0, + "average_temperature": 23.1333, + "experience_temperature": 22.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T05:50:06.306226+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.3, + "water_total": 286.0, + "average_temperature": 23.1333, + "experience_temperature": 22.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:00:06.503956+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.3, + "water_total": 286.0, + "average_temperature": 23.1333, + "experience_temperature": 22.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:10:06.166091+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 87.6, + "water_total": 294.0, + "average_temperature": 23.0333, + "experience_temperature": 23.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:20:06.959401+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 87.8, + "water_total": 298.0, + "average_temperature": 22.9333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:30:07.098789+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 88.1, + "water_total": 301.0, + "average_temperature": 22.9333, + "experience_temperature": 22.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:40:06.005998+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 88.4, + "water_total": 306.0, + "average_temperature": 22.8667, + "experience_temperature": 23.2467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T06:50:08.645937+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 88.3, + "water_total": 312.0, + "average_temperature": 22.9333, + "experience_temperature": 23.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:00:07.404320+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 87.7, + "water_total": 318.0, + "average_temperature": 23.1, + "experience_temperature": 23.04, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:10:07.501513+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 86.6, + "water_total": 324.0, + "average_temperature": 23.4333, + "experience_temperature": 23.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:20:06.860107+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 86.6, + "water_total": 324.0, + "average_temperature": 23.4333, + "experience_temperature": 23.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:30:07.652876+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 84.5, + "water_total": 332.0, + "average_temperature": 24.1, + "experience_temperature": 23.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:40:06.298210+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.1, + "humidity": 83.5, + "water_total": 333.0, + "average_temperature": 24.6333, + "experience_temperature": 24.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T07:50:07.638867+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 80.9, + "water_total": 339.0, + "average_temperature": 24.9667, + "experience_temperature": 23.5467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:00:08.344361+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.2, + "humidity": 80.9, + "water_total": 339.0, + "average_temperature": 24.9667, + "experience_temperature": 23.5467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:10:07.840397+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 79.8, + "water_total": 347.0, + "average_temperature": 25.5667, + "experience_temperature": 23.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:20:09.742498+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 76.7, + "water_total": 360.0, + "average_temperature": 26.4333, + "experience_temperature": 23.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:30:06.479463+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 75.8, + "water_total": 364.0, + "average_temperature": 26.7667, + "experience_temperature": 23.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:40:06.730918+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 74.9, + "water_total": 370.0, + "average_temperature": 27.2333, + "experience_temperature": 23.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T08:50:07.408243+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 73.2, + "water_total": 376.0, + "average_temperature": 27.8, + "experience_temperature": 24.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:00:07.879370+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 70.5, + "water_total": 382.0, + "average_temperature": 28.1667, + "experience_temperature": 22.5667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:10:07.366949+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 69.1, + "water_total": 390.0, + "average_temperature": 28.6333, + "experience_temperature": 22.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:20:07.353007+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 66.3, + "water_total": 397.0, + "average_temperature": 28.8, + "experience_temperature": 22.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:30:08.389300+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 65.7, + "water_total": 402.0, + "average_temperature": 29.1, + "experience_temperature": 22.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:40:06.713014+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 66.0, + "water_total": 411.0, + "average_temperature": 29.4333, + "experience_temperature": 21.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T09:50:06.759090+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 65.8, + "water_total": 419.0, + "average_temperature": 29.8667, + "experience_temperature": 22.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:00:10.494343+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 64.4, + "water_total": 427.0, + "average_temperature": 29.7333, + "experience_temperature": 22.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:10:07.275861+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 63.0, + "water_total": 434.0, + "average_temperature": 29.9667, + "experience_temperature": 21.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:20:13.839307+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 62.9, + "water_total": 442.0, + "average_temperature": 30.3, + "experience_temperature": 22.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:30:06.927439+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 60.5, + "water_total": 449.0, + "average_temperature": 30.2333, + "experience_temperature": 21.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:40:08.179413+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 59.2, + "water_total": 454.0, + "average_temperature": 30.2667, + "experience_temperature": 21.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T10:50:08.786347+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 61.1, + "water_total": 457.0, + "average_temperature": 30.7667, + "experience_temperature": 22.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:00:09.463637+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 60.5, + "water_total": 464.0, + "average_temperature": 30.5333, + "experience_temperature": 21.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:10:07.023675+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 61.9, + "water_total": 469.0, + "average_temperature": 30.6, + "experience_temperature": 22.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:20:07.766557+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 61.9, + "water_total": 469.0, + "average_temperature": 30.6, + "experience_temperature": 22.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:30:20.247934+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 70.5, + "water_total": 474.0, + "average_temperature": 28.1667, + "experience_temperature": 22.5667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:40:07.689474+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 62.9, + "water_total": 485.0, + "average_temperature": 30.6, + "experience_temperature": 22.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T11:50:07.356844+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 62.1, + "water_total": 489.0, + "average_temperature": 30.9333, + "experience_temperature": 22.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:00:07.724853+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 62.1, + "water_total": 492.0, + "average_temperature": 30.5, + "experience_temperature": 21.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:10:06.982993+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.5, + "humidity": 61.8, + "water_total": 498.0, + "average_temperature": 30.4, + "experience_temperature": 21.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:20:09.335921+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 59.3, + "water_total": 504.0, + "average_temperature": 30.9333, + "experience_temperature": 21.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:30:07.691673+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.5, + "humidity": 61.1, + "water_total": 509.0, + "average_temperature": 30.4, + "experience_temperature": 21.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:40:12.018231+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 62.5, + "water_total": 510.0, + "average_temperature": 30.2667, + "experience_temperature": 22.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T12:50:08.213424+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 60.3, + "water_total": 510.0, + "average_temperature": 30.9667, + "experience_temperature": 22.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:00:06.864211+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 61.7, + "water_total": 523.0, + "average_temperature": 30.1667, + "experience_temperature": 21.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:10:07.608333+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 65.0, + "water_total": 529.0, + "average_temperature": 30.3, + "experience_temperature": 22.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:20:11.222703+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 61.8, + "water_total": 530.0, + "average_temperature": 31.0, + "experience_temperature": 22.46, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:30:07.578459+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.5, + "humidity": 61.3, + "water_total": 530.0, + "average_temperature": 31.2333, + "experience_temperature": 21.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:40:07.209956+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 61.9, + "water_total": 535.0, + "average_temperature": 30.3333, + "experience_temperature": 21.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T13:50:07.489463+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 61.1, + "water_total": 548.0, + "average_temperature": 31.3, + "experience_temperature": 22.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T14:10:12.473842+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 60.6, + "water_total": 555.0, + "average_temperature": 30.6, + "experience_temperature": 21.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T14:20:06.142021+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 60.6, + "water_total": 555.0, + "average_temperature": 30.6, + "experience_temperature": 21.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T14:30:06.275772+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 59.4, + "water_total": 564.0, + "average_temperature": 30.2, + "experience_temperature": 20.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T14:40:08.334606+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 56.1, + "water_total": 584.0, + "average_temperature": 30.7333, + "experience_temperature": 20.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T14:50:13.826580+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.1, + "humidity": 55.2, + "water_total": 642.0, + "average_temperature": 30.2, + "experience_temperature": 20.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T15:10:31.496258+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.1, + "humidity": 56.9, + "water_total": 775.0, + "average_temperature": 30.8667, + "experience_temperature": 21.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T15:20:10.781576+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.1, + "humidity": 56.9, + "water_total": 775.0, + "average_temperature": 30.8667, + "experience_temperature": 21.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T15:30:08.062737+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 68.1, + "water_total": 900.0, + "average_temperature": 30.5, + "experience_temperature": 22.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T15:40:07.551097+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.2, + "humidity": 69.3, + "water_total": 970.0, + "average_temperature": 30.3, + "experience_temperature": 23.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T15:50:11.134893+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 69.8, + "water_total": 1001.0, + "average_temperature": 30.4333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T16:10:07.570773+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 69.5, + "water_total": 1016.0, + "average_temperature": 30.2333, + "experience_temperature": 22.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T16:20:07.218606+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 70.0, + "water_total": 1022.0, + "average_temperature": 30.1, + "experience_temperature": 22.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T16:30:07.940913+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 69.8, + "water_total": 1028.0, + "average_temperature": 29.9333, + "experience_temperature": 22.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T16:40:08.854308+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.4, + "humidity": 69.8, + "water_total": 1034.0, + "average_temperature": 29.7333, + "experience_temperature": 22.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T16:50:06.777361+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.5, + "humidity": 69.9, + "water_total": 1038.0, + "average_temperature": 29.6667, + "experience_temperature": 22.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T17:10:06.881481+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.3, + "humidity": 71.1, + "water_total": 5.0, + "average_temperature": 29.4333, + "experience_temperature": 22.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T17:20:06.908703+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.8, + "humidity": 72.1, + "water_total": 5.0, + "average_temperature": 29.1333, + "experience_temperature": 24.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T17:30:07.537599+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 73.1, + "water_total": 10.0, + "average_temperature": 28.9, + "experience_temperature": 23.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T17:40:06.436214+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.9, + "humidity": 74.1, + "water_total": 16.0, + "average_temperature": 28.6333, + "experience_temperature": 23.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T17:50:09.051637+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.0, + "humidity": 74.6, + "water_total": 23.0, + "average_temperature": 28.3667, + "experience_temperature": 23.2867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:00:06.368699+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 2.0, + "humidity": 75.2, + "water_total": 29.0, + "average_temperature": 28.1, + "experience_temperature": 23.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:10:06.879798+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.7, + "humidity": 76.5, + "water_total": 33.0, + "average_temperature": 27.8667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:20:06.516888+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 77.9, + "water_total": 35.0, + "average_temperature": 27.5667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:30:06.426030+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 78.7, + "water_total": 42.0, + "average_temperature": 27.4, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:40:06.300686+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 80.3, + "water_total": 48.0, + "average_temperature": 27.0, + "experience_temperature": 24.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T18:50:07.544705+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 80.9, + "water_total": 58.0, + "average_temperature": 26.9667, + "experience_temperature": 24.6467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:00:06.825586+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 82.5, + "water_total": 60.0, + "average_temperature": 26.6333, + "experience_temperature": 24.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:10:07.617939+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 83.3, + "water_total": 66.0, + "average_temperature": 26.4667, + "experience_temperature": 24.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:20:06.911790+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 83.9, + "water_total": 70.0, + "average_temperature": 26.3333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:30:06.719420+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 83.9, + "water_total": 70.0, + "average_temperature": 26.3333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:40:06.790028+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 84.5, + "water_total": 80.0, + "average_temperature": 26.4, + "experience_temperature": 24.5, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T19:50:06.740800+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 84.8, + "water_total": 87.0, + "average_temperature": 26.4333, + "experience_temperature": 25.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:00:06.741957+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.3, + "humidity": 85.1, + "water_total": 90.0, + "average_temperature": 26.2667, + "experience_temperature": 25.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:10:06.651953+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.5, + "water_total": 95.0, + "average_temperature": 25.9667, + "experience_temperature": 24.7667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:20:06.265728+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 86.7, + "water_total": 99.0, + "average_temperature": 26.1333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:30:10.571309+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 85.8, + "water_total": 104.0, + "average_temperature": 26.2333, + "experience_temperature": 24.8933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:40:07.534864+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.1, + "water_total": 109.0, + "average_temperature": 26.3, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T20:50:07.171043+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.1, + "water_total": 109.0, + "average_temperature": 26.3, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:00:06.811734+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 118.0, + "average_temperature": 26.2333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:10:06.471393+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.9, + "water_total": 123.0, + "average_temperature": 26.2333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:20:06.486442+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 87.0, + "water_total": 126.0, + "average_temperature": 26.2333, + "experience_temperature": 25.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:30:06.785018+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 86.6, + "water_total": 134.0, + "average_temperature": 26.4333, + "experience_temperature": 24.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:40:06.902177+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.4, + "water_total": 138.0, + "average_temperature": 26.5333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T21:50:06.640116+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 86.3, + "water_total": 147.0, + "average_temperature": 26.5333, + "experience_temperature": 25.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:00:07.405985+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 86.0, + "water_total": 154.0, + "average_temperature": 26.6, + "experience_temperature": 25.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:10:08.457131+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 159.0, + "average_temperature": 26.5, + "experience_temperature": 25.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:20:07.070123+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 87.1, + "water_total": 162.0, + "average_temperature": 26.3333, + "experience_temperature": 25.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:30:07.376229+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 86.6, + "water_total": 164.0, + "average_temperature": 26.3333, + "experience_temperature": 25.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:40:07.665010+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.1, + "water_total": 170.0, + "average_temperature": 26.3333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T22:50:06.502276+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 85.9, + "water_total": 176.0, + "average_temperature": 26.3333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:00:07.657078+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 182.0, + "average_temperature": 26.2667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:10:07.134670+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 87.0, + "water_total": 187.0, + "average_temperature": 26.1333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:20:07.209671+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.5, + "humidity": 86.9, + "water_total": 188.0, + "average_temperature": 26.0, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:30:06.297719+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 88.0, + "water_total": 188.0, + "average_temperature": 25.9333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:40:06.685453+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.4, + "humidity": 88.0, + "water_total": 188.0, + "average_temperature": 25.9333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-02T23:50:07.016867+07:00", + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 193.0, + "average_temperature": 25.7333, + "experience_temperature": 24.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:00:08.325490+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 88.3, + "water_total": 196.0, + "average_temperature": 25.5667, + "experience_temperature": 24.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:10:06.416482+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 88.3, + "water_total": 197.0, + "average_temperature": 25.5, + "experience_temperature": 24.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:20:07.251166+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 88.4, + "water_total": 200.0, + "average_temperature": 25.5333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:30:06.632892+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 88.7, + "water_total": 209.0, + "average_temperature": 25.4667, + "experience_temperature": 24.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:40:08.044475+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 89.0, + "water_total": 213.0, + "average_temperature": 25.3667, + "experience_temperature": 24.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T00:50:06.252752+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 89.2, + "water_total": 218.0, + "average_temperature": 25.2333, + "experience_temperature": 24.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:00:06.412007+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 89.2, + "water_total": 220.0, + "average_temperature": 25.1333, + "experience_temperature": 24.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:10:06.866406+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 89.4, + "water_total": 220.0, + "average_temperature": 25.0333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:20:06.588615+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 89.2, + "water_total": 225.0, + "average_temperature": 25.0667, + "experience_temperature": 24.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:30:06.628399+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 227.0, + "average_temperature": 25.0333, + "experience_temperature": 25.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:40:06.658498+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 88.8, + "water_total": 231.0, + "average_temperature": 24.9333, + "experience_temperature": 25.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T01:50:06.499324+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 89.6, + "water_total": 231.0, + "average_temperature": 24.7333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T02:00:06.401718+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 231.0, + "average_temperature": 24.7333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T02:10:06.294710+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 90.5, + "water_total": 234.0, + "average_temperature": 24.7667, + "experience_temperature": 25.5667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T02:20:08.338752+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 237.0, + "average_temperature": 24.7, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T02:30:06.630136+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 237.0, + "average_temperature": 24.7, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T02:50:06.265702+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.6, + "water_total": 246.0, + "average_temperature": 24.6333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:00:06.081241+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 90.6, + "water_total": 249.0, + "average_temperature": 24.7333, + "experience_temperature": 25.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:10:06.024204+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.6, + "water_total": 249.0, + "average_temperature": 24.7333, + "experience_temperature": 25.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:20:05.953025+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 90.3, + "water_total": 249.0, + "average_temperature": 24.7333, + "experience_temperature": 25.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:30:05.792775+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 249.0, + "average_temperature": 24.7333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:40:05.837095+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 249.0, + "average_temperature": 24.7333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T03:50:05.891497+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 90.4, + "water_total": 252.0, + "average_temperature": 24.6667, + "experience_temperature": 25.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:00:05.674242+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 90.4, + "water_total": 252.0, + "average_temperature": 24.6667, + "experience_temperature": 25.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:10:06.268417+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 258.0, + "average_temperature": 24.5333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:20:06.152149+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 258.0, + "average_temperature": 24.4333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:30:05.638392+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.0, + "water_total": 258.0, + "average_temperature": 24.4333, + "experience_temperature": 25.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:40:05.674021+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 91.2, + "water_total": 258.0, + "average_temperature": 24.4333, + "experience_temperature": 25.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T04:50:05.445735+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.3, + "water_total": 258.0, + "average_temperature": 24.4333, + "experience_temperature": 25.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:00:06.622908+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 259.0, + "average_temperature": 24.4333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:10:07.934369+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 91.4, + "water_total": 259.0, + "average_temperature": 24.4333, + "experience_temperature": 25.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:20:06.632424+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 259.0, + "average_temperature": 24.4, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:30:06.476379+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 259.0, + "average_temperature": 24.2667, + "experience_temperature": 24.9867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:40:06.764420+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 259.0, + "average_temperature": 24.2667, + "experience_temperature": 24.9867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T05:50:06.416339+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 259.0, + "average_temperature": 24.0667, + "experience_temperature": 24.8667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:00:07.624043+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 92.1, + "water_total": 259.0, + "average_temperature": 24.0, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:10:06.441059+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 261.0, + "average_temperature": 23.9, + "experience_temperature": 24.74, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:20:07.172391+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 261.0, + "average_temperature": 23.8, + "experience_temperature": 24.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:30:07.069733+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 261.0, + "average_temperature": 23.7333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:40:06.307945+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 261.0, + "average_temperature": 23.7333, + "experience_temperature": 24.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T06:50:06.785773+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 261.0, + "average_temperature": 23.9, + "experience_temperature": 24.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:00:06.751446+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 92.1, + "water_total": 261.0, + "average_temperature": 24.0667, + "experience_temperature": 25.1867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:10:07.548763+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.1, + "humidity": 92.0, + "water_total": 261.0, + "average_temperature": 24.3333, + "experience_temperature": 25.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:20:07.620315+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 91.5, + "water_total": 261.0, + "average_temperature": 24.5, + "experience_temperature": 25.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:30:06.845428+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 261.0, + "average_temperature": 24.7333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:40:06.568930+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 89.8, + "water_total": 261.0, + "average_temperature": 25.0667, + "experience_temperature": 24.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T07:50:06.675764+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 88.4, + "water_total": 261.0, + "average_temperature": 25.3667, + "experience_temperature": 24.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:00:07.215082+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 87.0, + "water_total": 261.0, + "average_temperature": 25.8, + "experience_temperature": 25.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:10:06.916649+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 84.7, + "water_total": 261.0, + "average_temperature": 26.2667, + "experience_temperature": 25.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:20:07.423268+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 84.7, + "water_total": 261.0, + "average_temperature": 26.2667, + "experience_temperature": 25.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:30:08.209207+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 79.9, + "water_total": 261.0, + "average_temperature": 27.2667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:40:06.731393+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 79.3, + "water_total": 261.0, + "average_temperature": 27.8, + "experience_temperature": 25.46, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T08:50:09.084824+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 77.2, + "water_total": 262.0, + "average_temperature": 28.1333, + "experience_temperature": 25.0733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:00:07.426861+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 76.9, + "water_total": 262.0, + "average_temperature": 28.5, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:10:08.152839+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 74.7, + "water_total": 262.0, + "average_temperature": 28.5333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:20:07.336267+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 74.7, + "water_total": 262.0, + "average_temperature": 28.5333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:30:07.190858+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 72.4, + "water_total": 262.0, + "average_temperature": 29.0667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:40:06.727520+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.8, + "humidity": 71.5, + "water_total": 262.0, + "average_temperature": 29.4333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T09:50:07.241884+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 70.4, + "water_total": 262.0, + "average_temperature": 29.4333, + "experience_temperature": 23.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:00:07.056377+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 69.9, + "water_total": 262.0, + "average_temperature": 29.8333, + "experience_temperature": 23.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:10:07.497183+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 69.1, + "water_total": 262.0, + "average_temperature": 30.0333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:20:06.804278+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 69.1, + "water_total": 262.0, + "average_temperature": 30.0333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:30:07.468306+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 68.5, + "water_total": 265.0, + "average_temperature": 30.1667, + "experience_temperature": 24.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:40:12.470890+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 67.9, + "water_total": 267.0, + "average_temperature": 30.4333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T10:50:06.791846+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 67.9, + "water_total": 267.0, + "average_temperature": 30.4333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:00:08.533416+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.8, + "water_total": 268.0, + "average_temperature": 30.6333, + "experience_temperature": 24.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:10:07.317674+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.8, + "humidity": 68.7, + "water_total": 269.0, + "average_temperature": 30.4667, + "experience_temperature": 24.8067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:20:06.612960+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.8, + "humidity": 68.7, + "water_total": 269.0, + "average_temperature": 30.4667, + "experience_temperature": 24.8067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:30:07.132659+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 66.5, + "water_total": 271.0, + "average_temperature": 30.4667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:40:06.970777+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.1, + "water_total": 274.0, + "average_temperature": 30.5, + "experience_temperature": 24.22, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T11:50:06.799760+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.1, + "water_total": 278.0, + "average_temperature": 30.7333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T12:00:09.944402+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.1, + "water_total": 280.0, + "average_temperature": 30.0667, + "experience_temperature": 23.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T12:10:07.024814+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 68.2, + "water_total": 284.0, + "average_temperature": 29.9, + "experience_temperature": 23.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T12:30:07.318817+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.1, + "humidity": 65.8, + "water_total": 291.0, + "average_temperature": 31.0, + "experience_temperature": 23.86, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T12:40:06.803220+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 67.5, + "water_total": 293.0, + "average_temperature": 29.7333, + "experience_temperature": 23.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T12:50:08.225630+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 68.4, + "water_total": 300.0, + "average_temperature": 30.1, + "experience_temperature": 24.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:00:06.076942+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 65.0, + "water_total": 302.0, + "average_temperature": 31.0, + "experience_temperature": 24.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:10:08.612004+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 65.5, + "water_total": 305.0, + "average_temperature": 30.8, + "experience_temperature": 24.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:20:07.640690+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 66.5, + "water_total": 306.0, + "average_temperature": 30.5, + "experience_temperature": 24.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:30:08.290112+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 66.6, + "water_total": 307.0, + "average_temperature": 30.4333, + "experience_temperature": 24.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:40:06.967177+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 66.2, + "water_total": 311.0, + "average_temperature": 30.3667, + "experience_temperature": 23.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T13:50:06.908770+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.1, + "humidity": 65.8, + "water_total": 313.0, + "average_temperature": 30.6333, + "experience_temperature": 23.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T14:10:06.943082+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 325.0, + "average_temperature": 30.3667, + "experience_temperature": 24.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T14:20:07.730646+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 66.7, + "water_total": 326.0, + "average_temperature": 30.2667, + "experience_temperature": 23.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T14:30:06.173107+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 65.0, + "water_total": 328.0, + "average_temperature": 30.9333, + "experience_temperature": 24.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T14:40:06.803007+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 62.3, + "water_total": 330.0, + "average_temperature": 30.9667, + "experience_temperature": 23.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T14:50:07.117711+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 67.5, + "water_total": 333.0, + "average_temperature": 30.5333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T15:10:07.675891+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 73.6, + "water_total": 340.0, + "average_temperature": 30.1667, + "experience_temperature": 24.8867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T15:20:10.209808+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 72.4, + "water_total": 343.0, + "average_temperature": 30.2333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T15:30:06.814761+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 72.4, + "water_total": 343.0, + "average_temperature": 30.2333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T15:40:06.850997+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 72.9, + "water_total": 348.0, + "average_temperature": 30.2333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T15:50:07.053026+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 72.8, + "water_total": 349.0, + "average_temperature": 30.4333, + "experience_temperature": 25.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T16:10:06.411091+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 73.2, + "water_total": 353.0, + "average_temperature": 30.0667, + "experience_temperature": 25.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T16:20:06.142012+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 73.6, + "water_total": 355.0, + "average_temperature": 29.7667, + "experience_temperature": 25.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T16:30:07.065807+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 73.6, + "water_total": 355.0, + "average_temperature": 29.7667, + "experience_temperature": 25.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T16:40:06.958635+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 74.4, + "water_total": 365.0, + "average_temperature": 29.6667, + "experience_temperature": 24.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T16:50:06.608721+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 74.6, + "water_total": 366.0, + "average_temperature": 29.6, + "experience_temperature": 24.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T17:10:07.822455+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.0, + "humidity": 75.1, + "water_total": 367.0, + "average_temperature": 29.4667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T17:20:06.437769+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 2.1, + "humidity": 76.2, + "water_total": 7.0, + "average_temperature": 29.2, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T17:30:06.643717+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 77.0, + "water_total": 8.0, + "average_temperature": 29.0333, + "experience_temperature": 24.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T17:40:05.806302+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.9, + "humidity": 77.0, + "water_total": 8.0, + "average_temperature": 29.0333, + "experience_temperature": 24.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T17:50:06.284462+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 78.1, + "water_total": 16.0, + "average_temperature": 28.7, + "experience_temperature": 25.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:00:06.774062+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 78.1, + "water_total": 16.0, + "average_temperature": 28.7, + "experience_temperature": 25.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:10:06.217649+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 77.8, + "water_total": 17.0, + "average_temperature": 28.7, + "experience_temperature": 25.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:20:06.419091+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 77.8, + "water_total": 17.0, + "average_temperature": 28.6333, + "experience_temperature": 25.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:30:06.571995+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 78.0, + "water_total": 17.0, + "average_temperature": 28.6, + "experience_temperature": 25.7, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:40:06.431849+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 75.3, + "water_total": 20.0, + "average_temperature": 28.7667, + "experience_temperature": 25.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T18:50:05.727237+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 74.8, + "water_total": 23.0, + "average_temperature": 28.8333, + "experience_temperature": 25.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:00:06.717527+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 74.4, + "water_total": 24.0, + "average_temperature": 28.8667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:10:05.812005+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 74.2, + "water_total": 25.0, + "average_temperature": 28.8, + "experience_temperature": 25.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:20:06.004379+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 74.0, + "water_total": 27.0, + "average_temperature": 28.7333, + "experience_temperature": 25.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:30:06.469650+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 74.1, + "water_total": 30.0, + "average_temperature": 28.6, + "experience_temperature": 24.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:40:06.724527+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 74.9, + "water_total": 32.0, + "average_temperature": 28.4333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T19:50:06.081925+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 75.5, + "water_total": 32.0, + "average_temperature": 28.2333, + "experience_temperature": 24.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:00:06.580227+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 76.4, + "water_total": 33.0, + "average_temperature": 28.1, + "experience_temperature": 24.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:10:07.807876+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 77.2, + "water_total": 33.0, + "average_temperature": 27.9667, + "experience_temperature": 24.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:20:06.976387+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 78.3, + "water_total": 34.0, + "average_temperature": 27.7333, + "experience_temperature": 24.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:30:06.151257+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 79.0, + "water_total": 38.0, + "average_temperature": 27.7333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:40:06.600006+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.7, + "humidity": 79.5, + "water_total": 38.0, + "average_temperature": 27.7, + "experience_temperature": 24.5, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T20:50:06.109627+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 79.5, + "water_total": 38.0, + "average_temperature": 27.7, + "experience_temperature": 25.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:00:06.331194+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 79.5, + "water_total": 39.0, + "average_temperature": 27.7333, + "experience_temperature": 24.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:10:06.791034+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 79.6, + "water_total": 39.0, + "average_temperature": 27.6333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:20:06.906254+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 79.8, + "water_total": 40.0, + "average_temperature": 27.6, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:30:06.946939+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 79.8, + "water_total": 40.0, + "average_temperature": 27.6, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:40:05.834061+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 81.3, + "water_total": 40.0, + "average_temperature": 27.1667, + "experience_temperature": 25.2267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T21:50:05.997357+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 81.0, + "water_total": 40.0, + "average_temperature": 27.2333, + "experience_temperature": 24.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:00:05.785892+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 81.0, + "water_total": 40.0, + "average_temperature": 27.2333, + "experience_temperature": 24.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:10:07.178425+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 81.0, + "water_total": 40.0, + "average_temperature": 27.2, + "experience_temperature": 25.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:20:05.795611+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 81.3, + "water_total": 40.0, + "average_temperature": 27.0667, + "experience_temperature": 25.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:30:07.516654+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 81.7, + "water_total": 40.0, + "average_temperature": 26.9333, + "experience_temperature": 24.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:40:06.114141+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 82.2, + "water_total": 40.0, + "average_temperature": 26.9333, + "experience_temperature": 24.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T22:50:06.040759+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.5, + "humidity": 82.6, + "water_total": 40.0, + "average_temperature": 26.9, + "experience_temperature": 24.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:00:06.482352+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 83.2, + "water_total": 40.0, + "average_temperature": 26.7667, + "experience_temperature": 24.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:10:06.001223+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 83.7, + "water_total": 40.0, + "average_temperature": 26.7333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:20:06.305902+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 40.0, + "average_temperature": 26.6, + "experience_temperature": 24.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:30:07.319909+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.4, + "humidity": 84.7, + "water_total": 40.0, + "average_temperature": 26.4333, + "experience_temperature": 25.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:40:06.258035+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 85.2, + "water_total": 40.0, + "average_temperature": 26.4333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-03T23:50:06.554336+07:00", + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 84.9, + "water_total": 40.0, + "average_temperature": 26.5667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:00:06.024673+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 84.9, + "water_total": 40.0, + "average_temperature": 26.5667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:10:06.537673+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 85.1, + "water_total": 40.0, + "average_temperature": 26.5, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:20:06.346340+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 85.3, + "water_total": 40.0, + "average_temperature": 26.5333, + "experience_temperature": 24.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:30:06.346292+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 85.5, + "water_total": 40.0, + "average_temperature": 26.5, + "experience_temperature": 24.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:40:06.186147+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 85.8, + "water_total": 40.0, + "average_temperature": 26.5333, + "experience_temperature": 24.8933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T00:50:05.985323+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 85.9, + "water_total": 40.0, + "average_temperature": 26.4667, + "experience_temperature": 25.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:00:06.442810+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 86.2, + "water_total": 40.0, + "average_temperature": 26.4, + "experience_temperature": 25.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:10:06.124371+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 86.2, + "water_total": 40.0, + "average_temperature": 26.3, + "experience_temperature": 25.04, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:20:06.179839+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 86.5, + "water_total": 40.0, + "average_temperature": 26.2, + "experience_temperature": 25.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:30:06.000420+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 86.7, + "water_total": 40.0, + "average_temperature": 26.0667, + "experience_temperature": 24.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:40:06.479217+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 87.0, + "water_total": 40.0, + "average_temperature": 25.9667, + "experience_temperature": 24.8667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T01:50:06.154489+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 87.2, + "water_total": 40.0, + "average_temperature": 25.9, + "experience_temperature": 24.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:00:06.526556+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 87.2, + "water_total": 40.0, + "average_temperature": 25.9, + "experience_temperature": 24.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:10:06.226330+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 87.5, + "water_total": 40.0, + "average_temperature": 25.7, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:20:06.036868+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 87.7, + "water_total": 40.0, + "average_temperature": 25.6333, + "experience_temperature": 24.0733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:30:06.095966+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 87.9, + "water_total": 40.0, + "average_temperature": 25.5333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:40:06.701375+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 87.9, + "water_total": 40.0, + "average_temperature": 25.5333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T02:50:06.105069+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.2, + "water_total": 40.0, + "average_temperature": 25.4, + "experience_temperature": 24.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:00:06.848806+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 88.2, + "water_total": 40.0, + "average_temperature": 25.3, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:10:06.080597+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.2, + "water_total": 40.0, + "average_temperature": 25.2333, + "experience_temperature": 24.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:20:06.998946+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.4, + "water_total": 40.0, + "average_temperature": 25.1333, + "experience_temperature": 24.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:30:06.051969+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.6, + "water_total": 40.0, + "average_temperature": 25.0667, + "experience_temperature": 24.2867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:40:06.162882+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.7, + "water_total": 40.0, + "average_temperature": 25.1, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T03:50:07.462849+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 88.7, + "water_total": 40.0, + "average_temperature": 25.1, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:00:06.769855+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 40.0, + "average_temperature": 25.0667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:10:07.339330+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 25.0, + "experience_temperature": 25.22, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:20:06.400114+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 24.9333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:30:05.914094+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 24.9, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:40:06.347479+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 24.9, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T04:50:05.817564+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 24.8333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:00:07.446517+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 40.0, + "average_temperature": 24.8, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:10:05.923112+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 40.0, + "average_temperature": 24.7667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:20:06.507767+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 88.9, + "water_total": 40.0, + "average_temperature": 24.7333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:30:06.624622+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 40.0, + "average_temperature": 24.6333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:40:07.225915+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 40.0, + "average_temperature": 24.6, + "experience_temperature": 24.86, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T05:50:07.211128+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.1, + "humidity": 89.7, + "water_total": 40.0, + "average_temperature": 24.5333, + "experience_temperature": 25.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:00:06.255904+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 40.0, + "average_temperature": 24.6, + "experience_temperature": 24.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:10:06.974338+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 40.0, + "average_temperature": 24.5333, + "experience_temperature": 24.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:20:06.142821+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 40.0, + "average_temperature": 24.5333, + "experience_temperature": 24.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:30:07.012465+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 90.8, + "water_total": 40.0, + "average_temperature": 24.5333, + "experience_temperature": 25.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:40:06.241101+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 40.0, + "average_temperature": 24.5, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T06:50:06.713191+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.1, + "humidity": 91.3, + "water_total": 40.0, + "average_temperature": 24.6, + "experience_temperature": 25.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:00:06.933021+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.1, + "humidity": 91.3, + "water_total": 40.0, + "average_temperature": 24.7333, + "experience_temperature": 25.6933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:10:06.429345+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.1, + "humidity": 91.0, + "water_total": 40.0, + "average_temperature": 24.9333, + "experience_temperature": 25.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:20:06.512469+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.1, + "humidity": 91.0, + "water_total": 40.0, + "average_temperature": 24.9333, + "experience_temperature": 25.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:30:06.513859+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 89.3, + "water_total": 40.0, + "average_temperature": 25.5333, + "experience_temperature": 24.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:40:06.447319+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 87.9, + "water_total": 40.0, + "average_temperature": 25.9667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T07:50:07.867614+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 85.8, + "water_total": 40.0, + "average_temperature": 26.3, + "experience_temperature": 24.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:00:19.242052+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 85.8, + "water_total": 40.0, + "average_temperature": 26.3, + "experience_temperature": 24.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:10:06.756199+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 83.6, + "water_total": 40.0, + "average_temperature": 26.9333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:20:06.334304+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 78.2, + "water_total": 40.0, + "average_temperature": 27.7, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:30:06.264772+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 76.8, + "water_total": 40.0, + "average_temperature": 28.0, + "experience_temperature": 24.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:40:06.408003+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 76.9, + "water_total": 40.0, + "average_temperature": 28.2333, + "experience_temperature": 25.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T08:50:06.415289+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 76.9, + "water_total": 40.0, + "average_temperature": 28.2333, + "experience_temperature": 25.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:00:05.830422+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 76.4, + "water_total": 40.0, + "average_temperature": 28.3, + "experience_temperature": 24.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:10:06.613169+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 75.1, + "water_total": 40.0, + "average_temperature": 28.9333, + "experience_temperature": 25.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:20:06.794405+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 74.4, + "water_total": 40.0, + "average_temperature": 29.0667, + "experience_temperature": 24.2467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:30:06.811021+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 72.9, + "water_total": 40.0, + "average_temperature": 29.4667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:40:07.315362+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 71.9, + "water_total": 40.0, + "average_temperature": 29.6667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T09:50:06.691541+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 71.8, + "water_total": 40.0, + "average_temperature": 29.9333, + "experience_temperature": 24.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:00:06.880407+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 70.7, + "water_total": 40.0, + "average_temperature": 30.0667, + "experience_temperature": 24.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:10:07.401348+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 70.7, + "water_total": 40.0, + "average_temperature": 30.1, + "experience_temperature": 24.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:20:07.584869+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 70.6, + "water_total": 40.0, + "average_temperature": 30.1333, + "experience_temperature": 24.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:30:07.447649+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 69.9, + "water_total": 40.0, + "average_temperature": 30.4333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:40:06.737046+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.7, + "water_total": 40.0, + "average_temperature": 30.6333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T10:50:08.488454+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.2, + "water_total": 40.0, + "average_temperature": 30.4, + "experience_temperature": 24.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:00:09.038572+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.8, + "humidity": 69.4, + "water_total": 40.0, + "average_temperature": 30.4333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:10:06.658075+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.5, + "water_total": 40.0, + "average_temperature": 30.6, + "experience_temperature": 24.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:20:06.524267+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 70.9, + "water_total": 40.0, + "average_temperature": 30.1333, + "experience_temperature": 24.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:30:07.219589+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 70.2, + "water_total": 40.0, + "average_temperature": 30.2667, + "experience_temperature": 24.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:40:06.692350+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 67.5, + "water_total": 40.0, + "average_temperature": 30.7, + "experience_temperature": 24.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T11:50:06.649608+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.0, + "water_total": 40.0, + "average_temperature": 30.2333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:00:07.151756+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.5, + "water_total": 40.0, + "average_temperature": 30.2667, + "experience_temperature": 24.4667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:10:07.351900+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.6, + "water_total": 40.0, + "average_temperature": 30.4333, + "experience_temperature": 24.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:20:07.382745+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.3, + "humidity": 65.3, + "water_total": 40.0, + "average_temperature": 31.0333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:30:07.124776+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.8, + "humidity": 68.9, + "water_total": 40.0, + "average_temperature": 30.7667, + "experience_temperature": 25.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:40:06.929705+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 68.6, + "water_total": 40.0, + "average_temperature": 30.6333, + "experience_temperature": 25.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T12:50:06.442113+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.2, + "humidity": 69.0, + "water_total": 40.0, + "average_temperature": 29.9667, + "experience_temperature": 23.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:00:07.014805+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.1, + "water_total": 40.0, + "average_temperature": 30.2, + "experience_temperature": 24.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:10:06.010782+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.3, + "humidity": 67.9, + "water_total": 40.0, + "average_temperature": 31.0333, + "experience_temperature": 23.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:20:07.987609+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 40.0, + "average_temperature": 30.7, + "experience_temperature": 24.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:30:06.528005+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.4, + "water_total": 40.0, + "average_temperature": 30.0, + "experience_temperature": 24.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:40:06.524989+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.5, + "water_total": 40.0, + "average_temperature": 30.4, + "experience_temperature": 24.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T13:50:06.738197+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.5, + "water_total": 40.0, + "average_temperature": 30.4, + "experience_temperature": 24.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T14:10:07.074884+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 71.6, + "water_total": 40.0, + "average_temperature": 29.9, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T14:20:07.112895+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.8, + "water_total": 40.0, + "average_temperature": 30.4, + "experience_temperature": 24.46, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T14:30:09.237037+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.5, + "humidity": 66.7, + "water_total": 40.0, + "average_temperature": 31.2333, + "experience_temperature": 23.0733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T14:40:07.321448+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 40.0, + "average_temperature": 30.1333, + "experience_temperature": 24.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T14:50:07.310399+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 71.2, + "water_total": 40.0, + "average_temperature": 29.9333, + "experience_temperature": 24.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T15:10:06.819609+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.4, + "water_total": 40.0, + "average_temperature": 30.7333, + "experience_temperature": 24.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T15:20:06.689187+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 69.9, + "water_total": 40.0, + "average_temperature": 30.2, + "experience_temperature": 24.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T15:30:08.032873+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.9, + "water_total": 40.0, + "average_temperature": 30.2333, + "experience_temperature": 24.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T15:40:06.608917+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 40.0, + "average_temperature": 30.7667, + "experience_temperature": 24.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T15:50:06.703061+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 67.8, + "water_total": 40.0, + "average_temperature": 30.6333, + "experience_temperature": 24.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T16:10:06.016702+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 69.0, + "water_total": 40.0, + "average_temperature": 30.2, + "experience_temperature": 24.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T16:20:06.164361+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.2, + "water_total": 40.0, + "average_temperature": 30.3333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T16:30:06.585583+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.2, + "water_total": 40.0, + "average_temperature": 30.4333, + "experience_temperature": 24.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T16:40:05.886897+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.2, + "water_total": 40.0, + "average_temperature": 30.4333, + "experience_temperature": 24.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T16:50:06.285201+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 67.2, + "water_total": 40.0, + "average_temperature": 30.4, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T17:10:05.731596+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.0, + "humidity": 67.8, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 23.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T17:20:05.957634+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 68.6, + "water_total": 0.0, + "average_temperature": 30.1333, + "experience_temperature": 24.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T17:30:05.940135+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 2.1, + "humidity": 69.5, + "water_total": 0.0, + "average_temperature": 30.0, + "experience_temperature": 23.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T17:40:06.709660+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 70.1, + "water_total": 0.0, + "average_temperature": 29.7333, + "experience_temperature": 24.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T17:50:06.012682+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 70.4, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 23.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:00:17.951150+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 70.4, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 23.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:10:05.374076+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 70.7, + "water_total": 0.0, + "average_temperature": 29.4333, + "experience_temperature": 23.8733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:20:05.790184+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 71.7, + "water_total": 0.0, + "average_temperature": 29.2333, + "experience_temperature": 24.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:30:05.861160+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 29.2333, + "experience_temperature": 24.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:40:05.545887+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.9, + "humidity": 74.2, + "water_total": 0.0, + "average_temperature": 29.1333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T18:50:06.066172+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 74.6, + "water_total": 0.0, + "average_temperature": 29.0333, + "experience_temperature": 25.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:00:06.761285+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 75.1, + "water_total": 0.0, + "average_temperature": 28.8667, + "experience_temperature": 24.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:10:06.345410+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 75.5, + "water_total": 0.0, + "average_temperature": 28.6667, + "experience_temperature": 24.9667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:20:06.647626+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 75.8, + "water_total": 0.0, + "average_temperature": 28.6, + "experience_temperature": 25.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:30:07.392460+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 28.5333, + "experience_temperature": 25.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:40:07.148471+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 77.3, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 24.8267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T19:50:07.053076+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 78.0, + "water_total": 0.0, + "average_temperature": 28.2667, + "experience_temperature": 25.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:00:06.095198+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 76.0, + "water_total": 0.0, + "average_temperature": 28.5667, + "experience_temperature": 25.2667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:10:06.444889+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 78.9, + "water_total": 0.0, + "average_temperature": 28.0333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:20:07.488029+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 79.5, + "water_total": 0.0, + "average_temperature": 27.9, + "experience_temperature": 25.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:30:07.003792+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 80.0, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:40:06.802872+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 80.2, + "water_total": 0.0, + "average_temperature": 27.7667, + "experience_temperature": 25.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T20:50:07.753927+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 80.6, + "water_total": 0.0, + "average_temperature": 27.7, + "experience_temperature": 25.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:00:06.864493+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 80.9, + "water_total": 0.0, + "average_temperature": 27.6333, + "experience_temperature": 25.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:10:06.272884+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 81.2, + "water_total": 0.0, + "average_temperature": 27.5667, + "experience_temperature": 25.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:20:07.096139+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 81.5, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 25.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:30:07.652613+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 81.9, + "water_total": 0.0, + "average_temperature": 27.3, + "experience_temperature": 25.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:40:06.951023+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 82.2, + "water_total": 0.0, + "average_temperature": 27.2, + "experience_temperature": 25.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T21:50:07.184667+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 82.6, + "water_total": 0.0, + "average_temperature": 27.0667, + "experience_temperature": 25.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:00:06.687008+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 82.5, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 24.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:10:06.550948+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 82.4, + "water_total": 0.0, + "average_temperature": 26.9, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:20:06.578121+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 82.9, + "water_total": 0.0, + "average_temperature": 26.7333, + "experience_temperature": 24.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:30:07.220604+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 83.2, + "water_total": 0.0, + "average_temperature": 26.6333, + "experience_temperature": 24.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:40:06.922300+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 83.8, + "water_total": 0.0, + "average_temperature": 26.5, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T22:50:06.310131+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 84.5, + "water_total": 0.0, + "average_temperature": 26.2667, + "experience_temperature": 24.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:00:05.982036+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.7, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 26.1667, + "experience_temperature": 24.0467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:10:06.830439+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 85.7, + "water_total": 0.0, + "average_temperature": 26.0, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:20:06.362533+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 86.0, + "water_total": 0.0, + "average_temperature": 25.7667, + "experience_temperature": 24.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:30:06.584518+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.5, + "humidity": 85.9, + "water_total": 0.0, + "average_temperature": 25.8, + "experience_temperature": 24.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:40:07.358644+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.4, + "humidity": 85.8, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 24.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-04T23:50:07.739366+07:00", + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 85.4, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:00:06.658512+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 85.7, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:10:07.045032+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 86.6, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 23.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:20:06.739384+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 0.0, + "average_temperature": 25.2333, + "experience_temperature": 24.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:30:06.591317+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 86.8, + "water_total": 0.0, + "average_temperature": 25.2333, + "experience_temperature": 23.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:40:07.114476+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 87.0, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 23.7667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T00:50:07.288137+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 87.4, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 24.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:00:06.962316+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 87.4, + "water_total": 0.0, + "average_temperature": 25.0333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:10:06.210403+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.7, + "humidity": 88.3, + "water_total": 0.0, + "average_temperature": 25.0333, + "experience_temperature": 23.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:20:06.607059+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 88.0, + "water_total": 0.0, + "average_temperature": 24.8, + "experience_temperature": 24.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:30:06.888906+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.3, + "humidity": 88.8, + "water_total": 0.0, + "average_temperature": 24.9333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:40:05.983904+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 24.9667, + "experience_temperature": 25.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T01:50:06.980772+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 24.8667, + "experience_temperature": 25.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:00:07.855955+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 25.04, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:10:07.113914+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 89.9, + "water_total": 0.0, + "average_temperature": 24.6333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:20:06.600810+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:30:07.664889+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 24.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:40:07.200255+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 88.9, + "water_total": 0.0, + "average_temperature": 24.3667, + "experience_temperature": 24.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T02:50:07.138250+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 0.0, + "average_temperature": 24.2667, + "experience_temperature": 24.4667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:00:06.421345+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 89.5, + "water_total": 0.0, + "average_temperature": 24.0667, + "experience_temperature": 24.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:10:06.508478+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.5, + "water_total": 0.0, + "average_temperature": 23.9667, + "experience_temperature": 24.2667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:20:07.017806+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:30:06.625027+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:40:06.669684+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.22, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T03:50:06.914567+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 90.2, + "water_total": 0.0, + "average_temperature": 23.8667, + "experience_temperature": 24.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:00:06.533439+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 90.6, + "water_total": 0.0, + "average_temperature": 23.9333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:10:06.971165+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 24.0667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:20:06.019147+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 91.1, + "water_total": 0.0, + "average_temperature": 23.8667, + "experience_temperature": 24.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:30:05.458057+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.0, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:40:05.772092+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.1, + "water_total": 0.0, + "average_temperature": 23.4667, + "experience_temperature": 24.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T04:50:09.022294+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 91.5, + "water_total": 0.0, + "average_temperature": 23.4, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:00:05.282660+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 91.5, + "water_total": 0.0, + "average_temperature": 23.4, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:10:05.147473+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 23.5, + "experience_temperature": 24.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:20:07.095430+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.7, + "water_total": 0.0, + "average_temperature": 23.3667, + "experience_temperature": 24.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:30:07.414729+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 23.3333, + "experience_temperature": 24.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:40:05.655610+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.2, + "experience_temperature": 24.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T05:50:06.594887+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 23.1667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:00:05.753247+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.2, + "experience_temperature": 24.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:10:05.690424+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 23.1667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:20:06.419013+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:30:05.597230+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:40:05.400244+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.2, + "experience_temperature": 24.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T06:50:06.278447+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.1, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.3667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:00:05.868449+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 91.7, + "water_total": 0.0, + "average_temperature": 23.5, + "experience_temperature": 24.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:10:05.660198+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.0, + "humidity": 91.3, + "water_total": 0.0, + "average_temperature": 23.6667, + "experience_temperature": 24.9267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:20:06.548500+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 90.4, + "water_total": 0.0, + "average_temperature": 24.0667, + "experience_temperature": 24.5467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:30:06.280227+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 24.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:40:06.110509+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 24.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T07:50:06.188489+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:00:06.225065+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 85.0, + "water_total": 0.0, + "average_temperature": 25.8667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:10:06.165264+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 85.0, + "water_total": 0.0, + "average_temperature": 25.8667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:20:06.672128+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 27.0, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:30:06.384316+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 27.0, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:40:06.334571+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 78.3, + "water_total": 0.0, + "average_temperature": 27.7667, + "experience_temperature": 24.6267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T08:50:06.661048+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.4, + "humidity": 77.2, + "water_total": 0.0, + "average_temperature": 28.0, + "experience_temperature": 25.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:00:05.997174+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 75.6, + "water_total": 0.0, + "average_temperature": 28.3667, + "experience_temperature": 24.9867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:10:07.452917+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 75.1, + "water_total": 0.0, + "average_temperature": 28.8, + "experience_temperature": 25.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:20:06.464224+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 73.1, + "water_total": 0.0, + "average_temperature": 28.9667, + "experience_temperature": 25.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:30:06.642177+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 0.0, + "average_temperature": 29.4, + "experience_temperature": 24.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:40:05.875468+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 71.4, + "water_total": 0.0, + "average_temperature": 29.5667, + "experience_temperature": 24.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T09:50:07.159261+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 30.0333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:00:20.744123+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 30.0333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:10:07.520646+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 67.6, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 23.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:20:07.104583+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 68.8, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 24.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:30:06.577167+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 66.8, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:40:06.074488+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 65.3, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 24.3933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T10:50:07.760815+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.2, + "humidity": 66.3, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 22.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:00:05.878464+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 64.7, + "water_total": 0.0, + "average_temperature": 30.6667, + "experience_temperature": 23.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:10:06.475727+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 66.5, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 24.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:20:06.250731+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 65.2, + "water_total": 0.0, + "average_temperature": 30.8, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:30:07.063130+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 65.9, + "water_total": 0.0, + "average_temperature": 30.6667, + "experience_temperature": 24.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:40:07.448972+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 66.3, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 24.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T11:50:05.781750+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 66.2, + "water_total": 0.0, + "average_temperature": 30.9, + "experience_temperature": 24.74, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:00:05.897672+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 62.7, + "water_total": 0.0, + "average_temperature": 30.9667, + "experience_temperature": 23.8067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:10:05.848285+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 66.3, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 23.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:20:05.502334+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 63.8, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 23.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:30:05.875015+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 62.8, + "water_total": 0.0, + "average_temperature": 30.9333, + "experience_temperature": 23.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:40:06.901374+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 64.7, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T12:50:07.451196+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 61.2, + "water_total": 0.0, + "average_temperature": 31.0333, + "experience_temperature": 23.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:00:06.021317+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 64.3, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 23.46, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:10:06.205259+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 67.4, + "water_total": 0.0, + "average_temperature": 29.9667, + "experience_temperature": 23.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:20:06.912231+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.3, + "humidity": 60.8, + "water_total": 0.0, + "average_temperature": 31.0333, + "experience_temperature": 22.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:30:07.456213+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 61.2, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 22.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:40:06.709247+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 64.8, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 23.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T13:50:06.863740+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 60.0, + "water_total": 0.0, + "average_temperature": 30.7667, + "experience_temperature": 23.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T14:10:07.577958+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 63.7, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 23.74, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T14:20:06.294422+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.3, + "humidity": 58.8, + "water_total": 0.0, + "average_temperature": 31.1333, + "experience_temperature": 21.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T14:30:06.837987+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.2, + "humidity": 61.8, + "water_total": 0.0, + "average_temperature": 31.2333, + "experience_temperature": 22.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T14:40:06.175022+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 65.5, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 23.7, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T14:50:06.240683+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 64.5, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 23.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T15:10:05.838601+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.3, + "humidity": 75.6, + "water_total": 0.0, + "average_temperature": 28.3667, + "experience_temperature": 25.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T15:20:06.986257+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 72.2, + "water_total": 0.0, + "average_temperature": 30.5, + "experience_temperature": 25.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T15:30:06.260022+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 71.9, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T15:40:06.929904+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 71.9, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T15:50:06.604844+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.1, + "humidity": 72.5, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 24.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T16:10:07.007616+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 25.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T16:20:06.075365+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 75.4, + "water_total": 0.0, + "average_temperature": 29.8, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T16:30:06.648892+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 76.0, + "water_total": 0.0, + "average_temperature": 29.5333, + "experience_temperature": 25.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T16:40:07.303718+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 75.4, + "water_total": 0.0, + "average_temperature": 29.6333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T16:50:06.577271+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 74.5, + "water_total": 0.0, + "average_temperature": 30.0, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T17:10:07.009285+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 73.9, + "water_total": 0.0, + "average_temperature": 29.9333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T17:20:06.852098+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 29.9, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T17:30:06.189608+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.0, + "humidity": 73.3, + "water_total": 0.0, + "average_temperature": 29.8333, + "experience_temperature": 24.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T17:40:06.145351+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 29.7333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T17:50:06.597513+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.1, + "humidity": 73.7, + "water_total": 0.0, + "average_temperature": 29.7333, + "experience_temperature": 24.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:00:06.667453+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 74.1, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 24.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:10:06.030830+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 74.7, + "water_total": 0.0, + "average_temperature": 29.5, + "experience_temperature": 24.74, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:20:06.449660+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 74.6, + "water_total": 0.0, + "average_temperature": 29.4333, + "experience_temperature": 24.6533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:30:07.069994+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 0.0, + "average_temperature": 29.4333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:40:06.611985+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.9, + "humidity": 74.7, + "water_total": 0.0, + "average_temperature": 29.4, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T18:50:06.776943+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 72.4, + "water_total": 0.0, + "average_temperature": 28.7333, + "experience_temperature": 24.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:00:06.840278+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 72.9, + "water_total": 0.0, + "average_temperature": 28.1667, + "experience_temperature": 23.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:10:07.610427+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.4, + "humidity": 73.3, + "water_total": 0.0, + "average_temperature": 28.2, + "experience_temperature": 24.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:20:06.141420+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 74.7, + "water_total": 0.0, + "average_temperature": 27.9667, + "experience_temperature": 24.4067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:30:06.880000+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 74.7, + "water_total": 0.0, + "average_temperature": 27.9667, + "experience_temperature": 24.4067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:40:07.322136+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 74.9, + "water_total": 0.0, + "average_temperature": 28.4333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T19:50:06.288304+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 74.9, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:00:06.419240+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.4, + "humidity": 75.1, + "water_total": 0.0, + "average_temperature": 28.4, + "experience_temperature": 25.22, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:10:06.962528+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 74.5, + "water_total": 0.0, + "average_temperature": 28.5, + "experience_temperature": 24.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:20:06.149326+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 75.6, + "water_total": 0.0, + "average_temperature": 28.1667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:30:06.631815+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 75.5, + "water_total": 0.0, + "average_temperature": 28.1, + "experience_temperature": 24.7, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:40:06.043775+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.4, + "humidity": 76.0, + "water_total": 0.0, + "average_temperature": 27.9667, + "experience_temperature": 24.9667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T20:50:06.511768+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.4, + "humidity": 76.8, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.8933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:00:06.463341+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 77.2, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:10:06.649144+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 77.2, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:20:06.346541+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 27.4667, + "experience_temperature": 24.3667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:30:09.485326+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.8, + "humidity": 79.8, + "water_total": 0.0, + "average_temperature": 27.2, + "experience_temperature": 23.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:40:06.973577+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 27.0333, + "experience_temperature": 24.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T21:50:07.631404+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 27.0333, + "experience_temperature": 24.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:00:11.417773+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 82.6, + "water_total": 0.0, + "average_temperature": 26.7333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:10:08.980824+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 84.1, + "water_total": 0.0, + "average_temperature": 26.5667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:20:08.986304+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 26.3667, + "experience_temperature": 24.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:30:07.686448+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 85.2, + "water_total": 0.0, + "average_temperature": 26.1667, + "experience_temperature": 24.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:40:07.121290+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 85.6, + "water_total": 0.0, + "average_temperature": 26.2333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T22:50:06.965423+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.7, + "humidity": 84.6, + "water_total": 0.0, + "average_temperature": 26.4667, + "experience_temperature": 24.2867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:00:06.646967+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 84.2, + "water_total": 0.0, + "average_temperature": 26.5, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:10:07.427262+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 26.3333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:20:08.329441+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.7, + "humidity": 85.9, + "water_total": 0.0, + "average_temperature": 26.1667, + "experience_temperature": 24.2467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:30:06.805221+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 86.6, + "water_total": 0.0, + "average_temperature": 25.9667, + "experience_temperature": 24.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:40:06.780513+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.6, + "humidity": 86.9, + "water_total": 0.0, + "average_temperature": 25.8667, + "experience_temperature": 24.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-05T23:50:06.440408+07:00", + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 87.3, + "water_total": 0.0, + "average_temperature": 25.8, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:00:07.463207+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 25.9, + "experience_temperature": 24.68, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:10:07.779428+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 25.9333, + "experience_temperature": 25.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:20:06.200801+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 25.5667, + "experience_temperature": 24.0467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:30:06.420312+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 25.5667, + "experience_temperature": 24.0467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:40:06.950693+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 89.0, + "water_total": 0.0, + "average_temperature": 25.3667, + "experience_temperature": 24.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T00:50:06.558401+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 25.2667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:00:06.670428+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 24.2467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:10:06.477734+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 25.0, + "experience_temperature": 25.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:20:06.572996+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 89.9, + "water_total": 0.0, + "average_temperature": 24.9333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:30:06.630267+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 24.9, + "experience_temperature": 25.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:40:06.890293+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 90.6, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 25.6533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T01:50:06.153437+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 90.7, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 25.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:00:06.995066+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.1, + "water_total": 0.0, + "average_temperature": 24.6667, + "experience_temperature": 25.2867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:10:06.888539+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.1, + "water_total": 0.0, + "average_temperature": 24.6667, + "experience_temperature": 25.2867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:20:06.531887+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.0, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:30:06.620786+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 90.8, + "water_total": 0.0, + "average_temperature": 24.2333, + "experience_temperature": 25.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:40:07.296845+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 0.0, + "average_temperature": 24.2333, + "experience_temperature": 24.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T02:50:08.009325+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.3333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:00:06.724328+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.8, + "water_total": 0.0, + "average_temperature": 24.2667, + "experience_temperature": 25.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:10:06.727103+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.2667, + "experience_temperature": 25.0467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:20:06.540296+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 24.3333, + "experience_temperature": 25.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:30:07.462908+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 92.3, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:40:07.416622+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T03:50:06.666414+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 0.0, + "average_temperature": 24.5667, + "experience_temperature": 25.3667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:00:07.215747+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 0.0, + "average_temperature": 24.5333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:10:07.344795+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.6, + "experience_temperature": 25.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:20:07.187753+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:30:06.956479+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:40:06.822906+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 0.0, + "average_temperature": 24.6667, + "experience_temperature": 25.5067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T04:50:07.804741+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:00:08.219344+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.3, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:10:07.564815+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:20:07.347664+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:30:06.817582+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.1, + "humidity": 92.3, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.6267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:40:05.545487+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T05:50:06.248982+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 24.1, + "experience_temperature": 24.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:00:06.068914+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 24.3, + "experience_temperature": 25.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:10:06.089371+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 24.3, + "experience_temperature": 25.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:20:06.095695+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 24.2667, + "experience_temperature": 25.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:30:06.458075+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.7, + "water_total": 0.0, + "average_temperature": 24.3333, + "experience_temperature": 25.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:40:05.685184+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.6, + "water_total": 0.0, + "average_temperature": 24.4, + "experience_temperature": 25.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T06:50:06.146401+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:00:05.956467+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 0.0, + "average_temperature": 24.6, + "experience_temperature": 25.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:10:05.848847+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 24.8, + "experience_temperature": 25.7, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:20:06.415181+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 92.2, + "water_total": 0.0, + "average_temperature": 25.0333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:30:07.355930+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:40:06.247131+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 25.5333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T07:50:06.129702+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 90.5, + "water_total": 0.0, + "average_temperature": 25.6, + "experience_temperature": 25.5, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:00:06.192951+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 90.5, + "water_total": 0.0, + "average_temperature": 25.6, + "experience_temperature": 25.5, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:10:06.260831+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 25.9333, + "experience_temperature": 25.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:20:06.817022+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 86.1, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 25.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:30:06.107617+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.4, + "water_total": 0.0, + "average_temperature": 27.5, + "experience_temperature": 25.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:40:06.203047+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 82.2, + "water_total": 0.0, + "average_temperature": 27.8, + "experience_temperature": 26.04, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T08:50:06.904602+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 80.5, + "water_total": 0.0, + "average_temperature": 28.3, + "experience_temperature": 25.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:00:07.089479+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 80.5, + "water_total": 0.0, + "average_temperature": 28.3, + "experience_temperature": 25.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:10:10.399571+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 76.6, + "water_total": 0.0, + "average_temperature": 29.0667, + "experience_temperature": 24.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:20:05.727829+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 74.6, + "water_total": 0.0, + "average_temperature": 29.2333, + "experience_temperature": 24.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:30:10.245716+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 71.8, + "water_total": 0.0, + "average_temperature": 29.7, + "experience_temperature": 24.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:40:07.068651+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 70.8, + "water_total": 0.0, + "average_temperature": 29.7, + "experience_temperature": 23.86, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T09:50:08.466240+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 72.2, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:00:07.890469+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 72.2, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 24.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:10:07.555912+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 70.9, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:20:07.134543+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 70.1, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:30:05.999227+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 70.1, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:40:06.638144+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 71.8, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 24.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T10:50:07.042748+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 71.2, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 25.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:00:07.165904+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 71.3, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:10:06.193148+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.1, + "humidity": 69.4, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 23.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:20:07.189849+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 68.6, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 24.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:30:07.678939+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 68.2, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 24.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:40:05.855876+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.2, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 30.6, + "experience_temperature": 24.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T11:50:07.612823+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.1, + "humidity": 70.9, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 24.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:00:06.644697+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 67.5, + "water_total": 0.0, + "average_temperature": 30.5, + "experience_temperature": 24.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:10:07.285594+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 68.6, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:20:08.954808+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 66.6, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 24.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:30:06.786018+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 68.4, + "water_total": 0.0, + "average_temperature": 30.9, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:40:06.424666+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 66.9, + "water_total": 0.0, + "average_temperature": 30.6667, + "experience_temperature": 24.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T12:50:05.948872+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 67.7, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:00:07.462697+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 69.6, + "water_total": 0.0, + "average_temperature": 29.9, + "experience_temperature": 23.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:10:08.304640+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 67.5, + "water_total": 0.0, + "average_temperature": 30.1667, + "experience_temperature": 23.9667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:20:06.607102+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 66.1, + "water_total": 0.0, + "average_temperature": 30.7667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:30:06.685621+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 66.1, + "water_total": 0.0, + "average_temperature": 30.7667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:40:06.659366+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 69.7, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 23.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T13:50:07.564247+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 71.1, + "water_total": 0.0, + "average_temperature": 29.8333, + "experience_temperature": 24.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T14:10:06.292509+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 66.0, + "water_total": 0.0, + "average_temperature": 30.5, + "experience_temperature": 24.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T14:20:06.359169+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 70.2, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T14:30:06.155687+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 68.1, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 24.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T14:40:06.456253+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 69.1, + "water_total": 0.0, + "average_temperature": 30.9333, + "experience_temperature": 25.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T14:50:08.491282+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 70.8, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T15:10:06.694048+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 30.1333, + "experience_temperature": 25.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T15:20:06.907197+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 72.3, + "water_total": 0.0, + "average_temperature": 30.1333, + "experience_temperature": 24.8933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T15:30:06.896954+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 72.2, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 25.1733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T15:40:07.499487+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 71.5, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 24.7667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T15:50:08.030687+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.1, + "humidity": 72.4, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 24.6133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T16:20:17.136658+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 24.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T16:30:14.473320+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.2, + "humidity": 70.5, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 23.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T16:40:13.048140+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 70.0, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T16:50:08.510305+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 69.9, + "water_total": 0.0, + "average_temperature": 29.8667, + "experience_temperature": 24.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T17:10:06.689020+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 2.0, + "humidity": 71.1, + "water_total": 0.0, + "average_temperature": 29.4333, + "experience_temperature": 23.6533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T17:20:07.355103+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 71.1, + "water_total": 0.0, + "average_temperature": 29.3333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T17:30:06.321022+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.9, + "humidity": 71.1, + "water_total": 0.0, + "average_temperature": 29.3333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T17:40:06.664632+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 72.2, + "water_total": 0.0, + "average_temperature": 28.9333, + "experience_temperature": 24.8733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T17:50:07.485575+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 73.1, + "water_total": 0.0, + "average_temperature": 28.7, + "experience_temperature": 24.52, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:00:06.399574+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 73.9, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 23.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:10:05.702452+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 75.4, + "water_total": 0.0, + "average_temperature": 28.1333, + "experience_temperature": 24.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:20:06.217022+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 75.4, + "water_total": 0.0, + "average_temperature": 28.1333, + "experience_temperature": 24.1133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:30:06.323030+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 27.8333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:40:07.364604+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 77.3, + "water_total": 0.0, + "average_temperature": 27.8667, + "experience_temperature": 24.8267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T18:50:06.166623+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 78.0, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:00:05.842978+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 78.8, + "water_total": 0.0, + "average_temperature": 27.6333, + "experience_temperature": 25.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:10:05.922620+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 24.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:20:07.092868+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 79.3, + "water_total": 0.0, + "average_temperature": 27.5667, + "experience_temperature": 24.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:30:05.960891+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 78.8, + "water_total": 0.0, + "average_temperature": 27.5333, + "experience_temperature": 24.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:40:08.491644+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 79.0, + "water_total": 0.0, + "average_temperature": 27.5333, + "experience_temperature": 24.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T19:50:06.003637+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 79.7, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:00:06.306033+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 79.7, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:10:08.725135+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 80.3, + "water_total": 0.0, + "average_temperature": 27.4667, + "experience_temperature": 25.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:20:07.243234+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 80.4, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:30:06.029260+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 27.4, + "experience_temperature": 25.04, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:40:05.726352+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.8, + "humidity": 81.2, + "water_total": 0.0, + "average_temperature": 27.2667, + "experience_temperature": 24.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T20:50:06.185700+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 81.6, + "water_total": 0.0, + "average_temperature": 27.3333, + "experience_temperature": 24.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:00:06.322497+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 81.8, + "water_total": 0.0, + "average_temperature": 27.2333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:10:06.831156+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 82.7, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 24.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:20:05.851180+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 26.4333, + "experience_temperature": 24.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:30:06.056657+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 0.0, + "average_temperature": 26.7333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:40:06.012605+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 84.4, + "water_total": 0.0, + "average_temperature": 26.6, + "experience_temperature": 24.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T21:50:05.684798+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 85.4, + "water_total": 0.0, + "average_temperature": 26.4667, + "experience_temperature": 24.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:00:06.092081+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 85.3, + "water_total": 0.0, + "average_temperature": 26.4333, + "experience_temperature": 24.6933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:10:06.067338+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 85.2, + "water_total": 0.0, + "average_temperature": 26.3667, + "experience_temperature": 25.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:20:06.648384+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 85.2, + "water_total": 0.0, + "average_temperature": 26.2667, + "experience_temperature": 24.5067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:30:06.351416+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 26.2, + "experience_temperature": 24.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:40:07.006925+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.5, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 26.2333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T22:50:05.766925+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 26.1333, + "experience_temperature": 24.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:00:06.364794+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 26.1333, + "experience_temperature": 24.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:10:05.801957+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 86.2, + "water_total": 0.0, + "average_temperature": 25.7667, + "experience_temperature": 24.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:20:06.130267+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.4, + "humidity": 86.4, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 24.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:30:06.645859+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.6, + "humidity": 86.5, + "water_total": 0.0, + "average_temperature": 25.6667, + "experience_temperature": 24.1667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:40:05.649243+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 86.7, + "water_total": 0.0, + "average_temperature": 25.6, + "experience_temperature": 23.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-06T23:50:05.661263+07:00", + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 23.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:00:05.406585+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 23.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:10:06.338415+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 87.7, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:20:05.938894+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.4, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 25.2667, + "experience_temperature": 24.6467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:30:06.000557+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 88.5, + "water_total": 0.0, + "average_temperature": 25.2333, + "experience_temperature": 23.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:40:07.150978+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 88.6, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 23.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T00:50:05.871917+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 24.5067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:00:05.441948+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 24.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:10:05.952821+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 24.9667, + "experience_temperature": 25.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:20:05.554732+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 24.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:30:06.348100+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 25.1667, + "experience_temperature": 24.3667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:40:05.619909+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 25.1333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T01:50:06.155498+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 90.2, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:00:05.572326+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 90.5, + "water_total": 0.0, + "average_temperature": 25.0333, + "experience_temperature": 24.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:10:06.729478+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 90.3, + "water_total": 0.0, + "average_temperature": 24.9333, + "experience_temperature": 25.3933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:20:05.748166+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 90.7, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 25.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:30:06.021877+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 25.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:40:05.971820+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.0, + "water_total": 0.0, + "average_temperature": 24.7333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T02:50:05.605307+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 24.6667, + "experience_temperature": 25.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:00:05.539449+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 24.6333, + "experience_temperature": 25.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:10:05.406655+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 24.5333, + "experience_temperature": 25.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:20:05.627914+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 0.0, + "average_temperature": 24.6333, + "experience_temperature": 25.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:30:06.453661+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 91.6, + "water_total": 0.0, + "average_temperature": 24.4667, + "experience_temperature": 25.1867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:40:05.709305+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 91.8, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T03:50:06.102057+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 0.0, + "average_temperature": 24.4, + "experience_temperature": 25.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:00:05.963490+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 0.0, + "average_temperature": 24.4, + "experience_temperature": 25.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:10:05.880757+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.0, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 24.2, + "experience_temperature": 25.68, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:20:06.420505+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.6, + "water_total": 0.0, + "average_temperature": 24.2, + "experience_temperature": 25.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:30:06.086992+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.9, + "water_total": 0.0, + "average_temperature": 24.1, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:40:05.260066+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.0, + "water_total": 0.0, + "average_temperature": 24.1333, + "experience_temperature": 25.1333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T04:50:06.207269+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.7, + "water_total": 0.0, + "average_temperature": 23.9667, + "experience_temperature": 24.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:00:06.495080+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 92.8, + "water_total": 0.0, + "average_temperature": 23.8667, + "experience_temperature": 24.8267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:10:06.304171+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 93.2, + "water_total": 0.0, + "average_temperature": 24.0, + "experience_temperature": 25.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:20:05.774059+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 0.0, + "average_temperature": 24.0667, + "experience_temperature": 25.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:30:05.820618+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 93.1, + "water_total": 0.0, + "average_temperature": 24.0333, + "experience_temperature": 25.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:40:06.392028+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 93.1, + "water_total": 0.0, + "average_temperature": 24.0333, + "experience_temperature": 25.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T05:50:05.324172+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.1, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:00:06.286214+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.1, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:10:06.725506+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 0.0, + "average_temperature": 23.9, + "experience_temperature": 24.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:20:07.593331+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 0.0, + "average_temperature": 23.8333, + "experience_temperature": 24.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:30:06.111773+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.5, + "water_total": 0.0, + "average_temperature": 23.8, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:40:06.889924+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.4, + "water_total": 0.0, + "average_temperature": 23.8667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T06:50:06.235348+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 93.6, + "water_total": 0.0, + "average_temperature": 23.8333, + "experience_temperature": 25.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:00:10.067867+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.1, + "humidity": 93.5, + "water_total": 0.0, + "average_temperature": 24.1, + "experience_temperature": 25.5, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:10:07.164576+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.3, + "humidity": 93.7, + "water_total": 0.0, + "average_temperature": 24.2667, + "experience_temperature": 25.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:20:06.146386+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.5, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.6, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:30:07.199387+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.5, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 25.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:40:06.703292+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.2, + "humidity": 93.1, + "water_total": 0.0, + "average_temperature": 24.9667, + "experience_temperature": 25.9867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T07:50:06.538469+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 25.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:00:06.376141+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 91.3, + "water_total": 0.0, + "average_temperature": 25.7667, + "experience_temperature": 25.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:10:06.678792+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 91.3, + "water_total": 0.0, + "average_temperature": 25.7667, + "experience_temperature": 25.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:20:07.309112+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 26.1333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:30:06.633671+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 86.2, + "water_total": 0.0, + "average_temperature": 27.2333, + "experience_temperature": 25.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:40:07.026428+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 84.2, + "water_total": 0.0, + "average_temperature": 27.7333, + "experience_temperature": 25.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T08:50:06.077469+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 82.5, + "water_total": 0.0, + "average_temperature": 28.0667, + "experience_temperature": 26.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:00:06.033903+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 28.5667, + "experience_temperature": 25.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:10:05.974410+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 28.5, + "experience_temperature": 25.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:20:09.956911+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 77.4, + "water_total": 0.0, + "average_temperature": 29.0, + "experience_temperature": 25.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:30:06.353244+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 77.4, + "water_total": 0.0, + "average_temperature": 29.0, + "experience_temperature": 25.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:40:07.664225+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 0.0, + "average_temperature": 29.2667, + "experience_temperature": 23.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T09:50:06.562232+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.1, + "humidity": 74.4, + "water_total": 0.0, + "average_temperature": 29.2667, + "experience_temperature": 23.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:00:06.098091+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 74.3, + "water_total": 0.0, + "average_temperature": 29.4333, + "experience_temperature": 24.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:10:06.464395+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 73.5, + "water_total": 0.0, + "average_temperature": 29.6333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:20:09.228208+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 0.0, + "average_temperature": 30.0333, + "experience_temperature": 24.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:30:08.189682+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 0.0, + "average_temperature": 30.0333, + "experience_temperature": 24.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:40:07.831428+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 71.4, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 24.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T10:50:07.382517+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 70.7, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:00:06.645619+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 70.7, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:10:06.949186+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 70.2, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 24.44, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:20:07.320153+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 68.5, + "water_total": 0.0, + "average_temperature": 30.6, + "experience_temperature": 24.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:30:06.784908+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 69.4, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 24.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:40:06.799239+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 69.1, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 24.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T11:50:08.954114+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.1, + "humidity": 69.1, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:00:06.520338+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.1, + "humidity": 69.1, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:10:06.643070+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 69.4, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 24.5467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:20:06.147942+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 69.3, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 24.3933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:30:06.290974+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 69.2, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 24.6067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:40:06.686623+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 67.0, + "water_total": 0.0, + "average_temperature": 30.7333, + "experience_temperature": 24.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T12:50:06.733344+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.1, + "humidity": 69.4, + "water_total": 0.0, + "average_temperature": 30.8667, + "experience_temperature": 24.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:00:06.797511+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 70.3, + "water_total": 0.0, + "average_temperature": 30.5667, + "experience_temperature": 24.9267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:10:06.619400+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.2, + "humidity": 71.5, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:20:06.552611+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 69.3, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 24.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:30:06.456604+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 68.5, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 24.3667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:40:08.558739+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.4, + "humidity": 68.7, + "water_total": 0.0, + "average_temperature": 31.1333, + "experience_temperature": 23.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T13:50:06.461544+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.8, + "humidity": 68.8, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 24.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T14:10:06.934475+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 69.2, + "water_total": 0.0, + "average_temperature": 30.8667, + "experience_temperature": 24.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T14:20:07.322255+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 66.0, + "water_total": 0.0, + "average_temperature": 30.7667, + "experience_temperature": 24.2667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T14:30:06.586580+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 67.3, + "water_total": 0.0, + "average_temperature": 30.6333, + "experience_temperature": 24.3933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T14:40:07.173985+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 71.0, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 24.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T14:50:08.504540+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 2.0, + "humidity": 74.1, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T15:10:07.597123+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 73.6, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 25.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T15:20:08.388586+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 72.6, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 25.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T15:30:07.544727+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 25.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T15:40:07.215062+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 73.0, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 25.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T15:50:10.349644+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.9, + "humidity": 73.8, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 25.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T16:10:07.440303+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 28.5, + "experience_temperature": 25.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T16:20:18.120252+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 73.1, + "water_total": 0.0, + "average_temperature": 28.8333, + "experience_temperature": 24.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T16:30:07.105955+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 73.7, + "water_total": 0.0, + "average_temperature": 28.7333, + "experience_temperature": 24.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T16:40:07.044190+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 73.6, + "water_total": 0.0, + "average_temperature": 28.8, + "experience_temperature": 24.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T16:50:09.209656+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 28.9333, + "experience_temperature": 24.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T17:10:06.560856+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 72.7, + "water_total": 0.0, + "average_temperature": 28.8667, + "experience_temperature": 24.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T17:20:07.259703+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 73.2, + "water_total": 0.0, + "average_temperature": 28.7667, + "experience_temperature": 24.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T17:30:07.167105+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 73.3, + "water_total": 0.0, + "average_temperature": 28.6333, + "experience_temperature": 24.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T17:40:06.706273+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 73.4, + "water_total": 0.0, + "average_temperature": 28.6, + "experience_temperature": 24.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T17:50:08.857918+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 74.3, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 24.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:00:06.200197+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 75.0, + "water_total": 0.0, + "average_temperature": 28.4, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:10:05.500022+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 76.1, + "water_total": 0.0, + "average_temperature": 28.2333, + "experience_temperature": 24.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:20:06.265950+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 77.8, + "water_total": 0.0, + "average_temperature": 27.9667, + "experience_temperature": 24.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:30:06.324607+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 79.4, + "water_total": 0.0, + "average_temperature": 27.6667, + "experience_temperature": 24.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:40:05.698137+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 77.5, + "water_total": 0.0, + "average_temperature": 27.9333, + "experience_temperature": 24.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T18:50:05.963489+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 77.0, + "water_total": 0.0, + "average_temperature": 27.9333, + "experience_temperature": 24.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:00:05.584254+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.4, + "humidity": 77.9, + "water_total": 0.0, + "average_temperature": 27.7, + "experience_temperature": 25.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:10:08.364688+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 79.6, + "water_total": 0.0, + "average_temperature": 27.3667, + "experience_temperature": 24.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:20:06.465121+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 27.6667, + "experience_temperature": 24.5667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:30:06.322500+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 80.5, + "water_total": 0.0, + "average_temperature": 27.6, + "experience_temperature": 24.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:40:06.264193+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 81.1, + "water_total": 0.0, + "average_temperature": 27.3333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T19:50:06.458939+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 80.4, + "water_total": 0.0, + "average_temperature": 27.3, + "experience_temperature": 24.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:00:06.695690+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 80.0, + "water_total": 0.0, + "average_temperature": 27.2333, + "experience_temperature": 24.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:10:06.101269+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 80.8, + "water_total": 0.0, + "average_temperature": 27.2, + "experience_temperature": 24.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:20:06.444493+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 81.2, + "water_total": 0.0, + "average_temperature": 26.9667, + "experience_temperature": 24.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:30:06.801544+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 81.6, + "water_total": 0.0, + "average_temperature": 27.1, + "experience_temperature": 24.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:40:07.348891+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 81.7, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 24.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T20:50:07.553206+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 82.3, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 24.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:00:06.845289+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 83.9, + "water_total": 0.0, + "average_temperature": 26.9667, + "experience_temperature": 25.2467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:10:07.963326+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 25.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:20:07.727365+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 26.7667, + "experience_temperature": 24.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:30:06.534132+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 26.7, + "experience_temperature": 25.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:40:08.983223+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 25.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T21:50:06.705701+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 25.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:00:07.181695+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 85.5, + "water_total": 0.0, + "average_temperature": 26.5333, + "experience_temperature": 24.8333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:10:07.273509+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 86.7, + "water_total": 0.0, + "average_temperature": 26.3667, + "experience_temperature": 24.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:20:06.795160+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.3, + "humidity": 87.0, + "water_total": 0.0, + "average_temperature": 26.2333, + "experience_temperature": 25.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:30:07.085181+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.3, + "humidity": 86.9, + "water_total": 0.0, + "average_temperature": 26.1, + "experience_temperature": 25.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:40:07.694448+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.3, + "humidity": 87.4, + "water_total": 0.0, + "average_temperature": 25.9333, + "experience_temperature": 25.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T22:50:06.735791+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 87.6, + "water_total": 0.0, + "average_temperature": 25.9, + "experience_temperature": 24.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:00:06.416237+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 88.2, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 24.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:10:07.049031+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 88.7, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 24.6733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:20:06.322665+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 88.6, + "water_total": 0.0, + "average_temperature": 25.5667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:30:06.685610+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.7, + "humidity": 88.6, + "water_total": 0.0, + "average_temperature": 25.5, + "experience_temperature": 24.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:40:06.410288+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.6, + "humidity": 88.6, + "water_total": 0.0, + "average_temperature": 25.4333, + "experience_temperature": 24.3533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-07T23:50:06.055256+07:00", + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:00:05.998184+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:10:06.553460+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 25.1333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:20:06.952903+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 25.1333, + "experience_temperature": 24.6533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:30:06.318221+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 25.2, + "experience_temperature": 24.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:40:07.576445+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 25.2333, + "experience_temperature": 24.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T00:50:06.186114+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 25.2, + "experience_temperature": 23.96, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:00:07.144975+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 88.8, + "water_total": 0.0, + "average_temperature": 25.2, + "experience_temperature": 23.86, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:10:06.330674+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 88.9, + "water_total": 0.0, + "average_temperature": 25.1333, + "experience_temperature": 23.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:20:06.419457+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 24.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:30:06.444388+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 24.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:40:06.613836+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 25.06, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T01:50:05.915120+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 90.5, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 25.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:00:06.346871+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 90.6, + "water_total": 0.0, + "average_temperature": 24.5667, + "experience_temperature": 25.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:10:05.866633+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 90.8, + "water_total": 0.0, + "average_temperature": 24.4333, + "experience_temperature": 24.9933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:20:07.079185+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 0.0, + "average_temperature": 24.3, + "experience_temperature": 24.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:30:07.227732+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 0.0, + "average_temperature": 24.2333, + "experience_temperature": 24.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:40:06.092915+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 0.0, + "average_temperature": 24.2333, + "experience_temperature": 24.8133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T02:50:06.278636+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 91.1, + "water_total": 0.0, + "average_temperature": 24.1333, + "experience_temperature": 24.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:00:07.363346+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 91.4, + "water_total": 0.0, + "average_temperature": 23.9667, + "experience_temperature": 24.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:10:07.456250+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 91.8, + "water_total": 0.0, + "average_temperature": 23.9333, + "experience_temperature": 24.6933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:20:07.090082+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 91.7, + "water_total": 0.0, + "average_temperature": 23.9, + "experience_temperature": 24.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:30:05.737112+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 91.9, + "water_total": 0.0, + "average_temperature": 23.9, + "experience_temperature": 24.68, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:40:06.556952+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.7333, + "experience_temperature": 24.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T03:50:06.790149+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.7667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:00:06.462051+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.7667, + "experience_temperature": 24.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:10:06.793560+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.0, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 24.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:20:06.437993+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 92.1, + "water_total": 0.0, + "average_temperature": 23.5, + "experience_temperature": 24.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:30:06.211924+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.2, + "water_total": 0.0, + "average_temperature": 23.5, + "experience_temperature": 24.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:40:06.435987+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.5, + "experience_temperature": 24.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T04:50:06.606418+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.4, + "water_total": 0.0, + "average_temperature": 23.4333, + "experience_temperature": 24.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:00:06.757211+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 23.4, + "experience_temperature": 24.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:10:06.472699+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 92.6, + "water_total": 0.0, + "average_temperature": 23.2667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:20:05.775514+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 92.6, + "water_total": 0.0, + "average_temperature": 23.2667, + "experience_temperature": 24.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:30:06.556205+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.7, + "water_total": 0.0, + "average_temperature": 23.2, + "experience_temperature": 24.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:40:06.302866+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.6, + "water_total": 0.0, + "average_temperature": 23.2333, + "experience_temperature": 24.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T05:50:06.513468+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 24.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:00:06.751363+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 24.0333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:10:06.389164+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 92.5, + "water_total": 0.0, + "average_temperature": 22.9667, + "experience_temperature": 23.8667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:20:06.537295+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 91.5, + "water_total": 0.0, + "average_temperature": 22.6667, + "experience_temperature": 23.3667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:30:06.548193+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 90.2, + "water_total": 0.0, + "average_temperature": 22.2333, + "experience_temperature": 22.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:40:06.915762+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 89.6, + "water_total": 0.0, + "average_temperature": 22.2667, + "experience_temperature": 22.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T06:50:06.623748+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 22.4333, + "experience_temperature": 22.6933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:00:06.381034+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 87.9, + "water_total": 0.0, + "average_temperature": 22.7, + "experience_temperature": 22.68, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:10:06.901797+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 86.8, + "water_total": 0.0, + "average_temperature": 23.0667, + "experience_temperature": 22.8267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:20:07.172805+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 23.4, + "experience_temperature": 22.74, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:30:07.236451+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 82.9, + "water_total": 0.0, + "average_temperature": 24.0667, + "experience_temperature": 23.0467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:40:06.657772+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 80.3, + "water_total": 0.0, + "average_temperature": 24.5667, + "experience_temperature": 23.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T07:50:06.621871+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 79.0, + "water_total": 0.0, + "average_temperature": 25.0667, + "experience_temperature": 22.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:00:06.476619+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 77.6, + "water_total": 0.0, + "average_temperature": 25.6, + "experience_temperature": 22.92, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:10:06.229865+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 75.8, + "water_total": 0.0, + "average_temperature": 25.9, + "experience_temperature": 22.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:20:08.645362+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 74.9, + "water_total": 0.0, + "average_temperature": 26.2333, + "experience_temperature": 22.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:30:06.061222+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 74.9, + "water_total": 0.0, + "average_temperature": 26.2333, + "experience_temperature": 22.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:40:06.735504+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 71.9, + "water_total": 0.0, + "average_temperature": 27.0333, + "experience_temperature": 22.9133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T08:50:07.050090+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 70.3, + "water_total": 0.0, + "average_temperature": 27.5333, + "experience_temperature": 23.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:00:06.706341+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 68.1, + "water_total": 0.0, + "average_temperature": 28.2333, + "experience_temperature": 22.1533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:10:06.679058+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 67.7, + "water_total": 0.0, + "average_temperature": 28.6, + "experience_temperature": 22.44, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:20:08.153998+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 66.4, + "water_total": 0.0, + "average_temperature": 28.8, + "experience_temperature": 22.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:30:06.172657+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 62.8, + "water_total": 0.0, + "average_temperature": 29.1, + "experience_temperature": 21.06, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:40:11.911741+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 61.2, + "water_total": 0.0, + "average_temperature": 29.6667, + "experience_temperature": 21.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T09:50:07.056635+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 60.5, + "water_total": 0.0, + "average_temperature": 30.0667, + "experience_temperature": 21.2667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:00:07.500373+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 59.9, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 21.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:10:09.439796+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.6, + "water_total": 0.0, + "average_temperature": 29.9333, + "experience_temperature": 21.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:20:06.728390+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 60.4, + "water_total": 0.0, + "average_temperature": 30.2667, + "experience_temperature": 21.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:30:08.635321+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 59.4, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 21.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:40:07.147213+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.5, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 21.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T10:50:08.727486+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.5, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 21.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:00:07.228835+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.7, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 22.0733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:10:07.261057+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.5, + "water_total": 0.0, + "average_temperature": 30.1, + "experience_temperature": 21.2, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:20:09.316717+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.2, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 21.34, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:30:09.005937+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 60.1, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 21.42, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:40:07.573416+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 61.6, + "water_total": 0.0, + "average_temperature": 30.3333, + "experience_temperature": 21.7533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T11:50:08.222100+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.6, + "water_total": 0.0, + "average_temperature": 30.9, + "experience_temperature": 22.42, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:00:07.213929+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.5, + "water_total": 0.0, + "average_temperature": 30.5667, + "experience_temperature": 21.6667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:10:08.923773+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 58.2, + "water_total": 0.0, + "average_temperature": 31.0333, + "experience_temperature": 21.4733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:20:07.501463+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 58.7, + "water_total": 0.0, + "average_temperature": 30.5667, + "experience_temperature": 21.4067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:30:07.246000+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 61.6, + "water_total": 0.0, + "average_temperature": 30.0, + "experience_temperature": 21.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:40:09.602204+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.5, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 21.5667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T12:50:07.754380+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.8, + "humidity": 58.8, + "water_total": 0.0, + "average_temperature": 31.0667, + "experience_temperature": 20.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:00:06.926303+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.8, + "humidity": 58.8, + "water_total": 0.0, + "average_temperature": 31.0667, + "experience_temperature": 20.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:10:07.528295+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.1, + "water_total": 0.0, + "average_temperature": 30.6667, + "experience_temperature": 22.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:20:06.810679+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 59.3, + "water_total": 0.0, + "average_temperature": 30.5333, + "experience_temperature": 21.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:30:07.343470+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.4, + "humidity": 61.9, + "water_total": 0.0, + "average_temperature": 30.5667, + "experience_temperature": 21.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:40:07.487415+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 57.5, + "water_total": 0.0, + "average_temperature": 31.0, + "experience_temperature": 21.9, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T13:50:09.165361+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.2, + "humidity": 60.8, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 21.96, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T14:10:07.895326+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.5, + "humidity": 59.9, + "water_total": 0.0, + "average_temperature": 30.7, + "experience_temperature": 21.18, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T14:20:07.148048+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.3, + "humidity": 61.1, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 21.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T14:30:07.629257+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.5, + "humidity": 65.4, + "water_total": 0.0, + "average_temperature": 30.3, + "experience_temperature": 21.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T14:40:08.956215+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.7, + "humidity": 63.3, + "water_total": 0.0, + "average_temperature": 31.2333, + "experience_temperature": 21.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T14:50:06.906185+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.1, + "humidity": 67.6, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 23.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T15:10:06.568002+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 68.8, + "water_total": 0.0, + "average_temperature": 30.1667, + "experience_temperature": 24.2267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T15:20:07.112282+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.8, + "humidity": 65.9, + "water_total": 0.0, + "average_temperature": 30.3667, + "experience_temperature": 24.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T15:30:07.801130+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 66.4, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 23.98, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T15:40:07.352326+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.1, + "humidity": 65.4, + "water_total": 0.0, + "average_temperature": 30.4333, + "experience_temperature": 23.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T15:50:07.132012+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.0, + "humidity": 65.2, + "water_total": 0.0, + "average_temperature": 30.4, + "experience_temperature": 23.44, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T16:10:07.606511+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.0, + "humidity": 65.2, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 23.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T16:20:06.713435+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.0, + "humidity": 65.8, + "water_total": 0.0, + "average_temperature": 30.0, + "experience_temperature": 23.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T16:30:08.207855+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.0, + "humidity": 66.8, + "water_total": 0.0, + "average_temperature": 29.9, + "experience_temperature": 23.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T16:40:07.645939+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 66.3, + "water_total": 0.0, + "average_temperature": 29.7333, + "experience_temperature": 23.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T16:50:07.629500+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 66.1, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 23.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T17:10:10.498275+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 2.0, + "humidity": 67.2, + "water_total": 0.0, + "average_temperature": 29.2667, + "experience_temperature": 22.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T17:20:08.813587+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.9, + "humidity": 67.5, + "water_total": 0.0, + "average_temperature": 29.0667, + "experience_temperature": 22.8667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T17:30:07.266138+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 67.7, + "water_total": 0.0, + "average_temperature": 28.7, + "experience_temperature": 23.44, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T17:40:06.823764+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 69.0, + "water_total": 0.0, + "average_temperature": 28.4333, + "experience_temperature": 23.4333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T17:50:06.768673+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 68.9, + "water_total": 0.0, + "average_temperature": 28.2, + "experience_temperature": 23.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:00:09.295943+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 71.1, + "water_total": 0.0, + "average_temperature": 27.7667, + "experience_temperature": 22.8867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:10:07.047462+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 70.9, + "water_total": 0.0, + "average_temperature": 27.7, + "experience_temperature": 23.08, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:20:06.930212+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 73.5, + "water_total": 0.0, + "average_temperature": 27.1667, + "experience_temperature": 23.0667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:30:08.107195+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 75.0, + "water_total": 0.0, + "average_temperature": 26.9, + "experience_temperature": 23.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:40:09.415444+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 75.3, + "water_total": 0.0, + "average_temperature": 26.9333, + "experience_temperature": 23.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T18:50:07.288350+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.8, + "humidity": 75.3, + "water_total": 0.0, + "average_temperature": 26.9, + "experience_temperature": 22.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:00:06.940700+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.8, + "humidity": 75.3, + "water_total": 0.0, + "average_temperature": 26.9, + "experience_temperature": 22.56, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:10:06.589352+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 75.9, + "water_total": 0.0, + "average_temperature": 26.8, + "experience_temperature": 23.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:20:07.222823+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 76.4, + "water_total": 0.0, + "average_temperature": 27.0333, + "experience_temperature": 23.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:30:05.867877+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 75.6, + "water_total": 0.0, + "average_temperature": 27.0, + "experience_temperature": 23.62, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:40:06.530618+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 75.4, + "water_total": 0.0, + "average_temperature": 27.1, + "experience_temperature": 23.38, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T19:50:28.781911+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 23.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:00:06.318477+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 76.7, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 23.1067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:10:05.765838+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 77.3, + "water_total": 0.0, + "average_temperature": 26.7, + "experience_temperature": 23.66, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:20:06.560361+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 77.3, + "water_total": 0.0, + "average_temperature": 26.7333, + "experience_temperature": 23.3933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:30:10.436157+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 78.1, + "water_total": 0.0, + "average_temperature": 26.5, + "experience_temperature": 23.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:40:06.908872+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 78.1, + "water_total": 0.0, + "average_temperature": 26.4333, + "experience_temperature": 23.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T20:50:05.685268+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 77.7, + "water_total": 0.0, + "average_temperature": 26.5667, + "experience_temperature": 23.3067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:00:05.899955+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 77.2, + "water_total": 0.0, + "average_temperature": 26.6, + "experience_temperature": 23.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:10:06.501780+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.1, + "humidity": 77.7, + "water_total": 0.0, + "average_temperature": 26.5667, + "experience_temperature": 24.8067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:20:05.835526+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 78.6, + "water_total": 0.0, + "average_temperature": 26.3333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:30:06.711276+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.2, + "humidity": 79.8, + "water_total": 0.0, + "average_temperature": 26.0, + "experience_temperature": 24.36, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:40:06.215182+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 80.2, + "water_total": 0.0, + "average_temperature": 25.9, + "experience_temperature": 23.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T21:50:06.088270+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 80.5, + "water_total": 0.0, + "average_temperature": 25.6333, + "experience_temperature": 22.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:00:07.029752+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 80.5, + "water_total": 0.0, + "average_temperature": 25.6333, + "experience_temperature": 22.6333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:10:05.554731+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 25.9, + "experience_temperature": 22.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:20:05.869165+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 80.4, + "water_total": 0.0, + "average_temperature": 25.8667, + "experience_temperature": 23.4467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:30:07.524072+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 80.4, + "water_total": 0.0, + "average_temperature": 25.7667, + "experience_temperature": 22.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:40:06.304471+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 81.3, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 23.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T22:50:06.551329+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 81.6, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 23.52, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:00:06.783485+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 82.2, + "water_total": 0.0, + "average_temperature": 25.6333, + "experience_temperature": 22.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:10:05.761168+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.5, + "humidity": 82.7, + "water_total": 0.0, + "average_temperature": 25.5, + "experience_temperature": 23.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:20:06.011676+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 83.1, + "water_total": 0.0, + "average_temperature": 25.4333, + "experience_temperature": 23.8533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:30:06.333039+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.6, + "humidity": 82.4, + "water_total": 0.0, + "average_temperature": 25.6667, + "experience_temperature": 23.3467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:40:06.342871+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.7, + "humidity": 81.9, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 23.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-08T23:50:06.127090+07:00", + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 82.3, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 23.96, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:00:05.563129+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.4, + "humidity": 82.3, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 23.96, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:10:05.547008+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.5, + "humidity": 83.9, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 23.68, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:20:05.638570+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.6, + "humidity": 84.1, + "water_total": 0.0, + "average_temperature": 25.2333, + "experience_temperature": 23.2533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:30:05.645078+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.6, + "humidity": 84.2, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 23.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:40:06.089438+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.6, + "humidity": 84.1, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 23.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T00:50:06.110468+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.3, + "humidity": 84.2, + "water_total": 0.0, + "average_temperature": 25.0667, + "experience_temperature": 24.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:00:06.058969+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.3, + "humidity": 84.4, + "water_total": 0.0, + "average_temperature": 25.0333, + "experience_temperature": 24.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:10:05.672260+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 84.5, + "water_total": 0.0, + "average_temperature": 25.0, + "experience_temperature": 24.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:20:06.171045+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 84.7, + "water_total": 0.0, + "average_temperature": 24.9333, + "experience_temperature": 24.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:30:06.861315+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 84.8, + "water_total": 0.0, + "average_temperature": 24.9333, + "experience_temperature": 24.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:40:07.221410+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 84.9, + "water_total": 0.0, + "average_temperature": 24.8, + "experience_temperature": 24.48, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T01:50:06.106555+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 85.3, + "water_total": 0.0, + "average_temperature": 24.7, + "experience_temperature": 24.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:00:06.176066+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 85.8, + "water_total": 0.0, + "average_temperature": 24.5667, + "experience_temperature": 24.4267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:10:06.679762+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 86.3, + "water_total": 0.0, + "average_temperature": 24.4333, + "experience_temperature": 24.0933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:20:06.135112+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 86.7, + "water_total": 0.0, + "average_temperature": 24.2333, + "experience_temperature": 23.9733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:30:05.638194+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 87.6, + "water_total": 0.0, + "average_temperature": 24.1667, + "experience_temperature": 24.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:40:05.520362+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 88.1, + "water_total": 0.0, + "average_temperature": 24.1, + "experience_temperature": 24.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T02:50:05.825705+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 88.4, + "water_total": 0.0, + "average_temperature": 23.9333, + "experience_temperature": 24.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:00:06.329989+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 88.4, + "water_total": 0.0, + "average_temperature": 23.7667, + "experience_temperature": 23.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:10:06.216620+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 88.8, + "water_total": 0.0, + "average_temperature": 23.6667, + "experience_temperature": 23.8267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:20:05.668266+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 89.1, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 24.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:30:06.361306+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.1, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 23.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:40:07.177811+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 23.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T03:50:06.087418+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 23.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:00:05.892541+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 23.86, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:10:06.066457+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 23.6, + "experience_temperature": 24.16, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:20:05.891204+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 23.5667, + "experience_temperature": 23.8067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:30:05.845819+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 23.4333, + "experience_temperature": 23.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:40:05.813833+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.4, + "water_total": 0.0, + "average_temperature": 23.4333, + "experience_temperature": 23.7133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T04:50:06.284125+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 23.3, + "experience_temperature": 23.64, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:00:05.922874+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 23.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:10:06.265345+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 23.1333, + "experience_temperature": 23.4933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:20:06.338126+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 23.0667, + "experience_temperature": 23.7067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:30:07.261402+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.0, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 23.0667, + "experience_temperature": 24.0067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:40:05.737031+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.5, + "water_total": 0.0, + "average_temperature": 23.0, + "experience_temperature": 23.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T05:50:06.290788+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 22.9, + "experience_temperature": 23.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:00:05.900476+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 89.9, + "water_total": 0.0, + "average_temperature": 22.9, + "experience_temperature": 23.58, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:10:06.334907+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 22.9333, + "experience_temperature": 23.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:20:05.702511+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.8, + "water_total": 0.0, + "average_temperature": 22.9333, + "experience_temperature": 23.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:30:07.279263+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 90.0, + "water_total": 0.0, + "average_temperature": 22.9, + "experience_temperature": 23.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:40:06.061109+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 90.2, + "water_total": 0.0, + "average_temperature": 22.9333, + "experience_temperature": 23.3733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T06:50:06.492701+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.3, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 23.1, + "experience_temperature": 23.22, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:00:07.836992+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.7, + "water_total": 0.0, + "average_temperature": 23.2333, + "experience_temperature": 23.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:10:06.294987+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 89.2, + "water_total": 0.0, + "average_temperature": 23.5333, + "experience_temperature": 23.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:20:05.953522+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 88.8, + "water_total": 0.0, + "average_temperature": 23.7333, + "experience_temperature": 24.1933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:30:06.479799+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 88.2, + "water_total": 0.0, + "average_temperature": 24.1, + "experience_temperature": 24.44, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:40:07.040322+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.1, + "humidity": 87.2, + "water_total": 0.0, + "average_temperature": 24.4, + "experience_temperature": 24.54, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T07:50:06.213749+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 85.9, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 24.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:00:07.339325+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.2, + "humidity": 85.9, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 24.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:10:06.268035+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 1.5, + "humidity": 84.5, + "water_total": 0.0, + "average_temperature": 25.3333, + "experience_temperature": 23.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:20:08.319694+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 82.4, + "water_total": 0.0, + "average_temperature": 26.4, + "experience_temperature": 26.78, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:30:07.583515+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.0, + "humidity": 80.7, + "water_total": 0.0, + "average_temperature": 26.8, + "experience_temperature": 28.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:40:06.473993+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.0, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 26.0667, + "experience_temperature": 29.9267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T08:50:06.725651+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.0, + "humidity": 89.3, + "water_total": 0.0, + "average_temperature": 26.0667, + "experience_temperature": 29.9267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:00:06.694088+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 78.8, + "water_total": 0.0, + "average_temperature": 28.1667, + "experience_temperature": 28.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:10:06.542241+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 75.0, + "water_total": 0.0, + "average_temperature": 28.6333, + "experience_temperature": 27.5333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:20:07.225815+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 72.8, + "water_total": 0.0, + "average_temperature": 29.2667, + "experience_temperature": 28.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:30:13.154302+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 29.8667, + "experience_temperature": 27.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:40:07.021629+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 68.3, + "water_total": 0.0, + "average_temperature": 30.0667, + "experience_temperature": 27.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T09:50:07.198772+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 68.3, + "water_total": 0.0, + "average_temperature": 30.0667, + "experience_temperature": 27.3267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:00:06.796059+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 67.1, + "water_total": 0.0, + "average_temperature": 30.4667, + "experience_temperature": 27.4867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:10:08.600985+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 61.7, + "water_total": 0.0, + "average_temperature": 31.0333, + "experience_temperature": 27.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:20:06.519003+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 62.1, + "water_total": 0.0, + "average_temperature": 31.3, + "experience_temperature": 27.32, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:30:06.555229+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 63.3, + "water_total": 0.0, + "average_temperature": 31.6667, + "experience_temperature": 27.9267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:40:06.208532+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 59.3, + "water_total": 0.0, + "average_temperature": 31.8333, + "experience_temperature": 27.5933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T10:50:07.167391+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 59.5, + "water_total": 0.0, + "average_temperature": 32.0, + "experience_temperature": 28.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:00:10.377124+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 56.8, + "water_total": 0.0, + "average_temperature": 32.1667, + "experience_temperature": 27.7267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:10:06.511011+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 54.3, + "water_total": 0.0, + "average_temperature": 32.2667, + "experience_temperature": 27.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:20:07.151357+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 53.1, + "water_total": 0.0, + "average_temperature": 32.7333, + "experience_temperature": 27.5533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:30:06.765614+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 52.9, + "water_total": 0.0, + "average_temperature": 32.8, + "experience_temperature": 27.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:40:07.635283+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 51.9, + "water_total": 0.0, + "average_temperature": 33.0333, + "experience_temperature": 27.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T11:50:05.776440+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 51.9, + "water_total": 0.0, + "average_temperature": 33.0333, + "experience_temperature": 27.0133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:00:06.661279+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 51.3, + "water_total": 0.0, + "average_temperature": 33.3333, + "experience_temperature": 27.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:10:07.588443+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 50.7, + "water_total": 0.0, + "average_temperature": 33.5333, + "experience_temperature": 27.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:20:06.337069+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 50.7, + "water_total": 0.0, + "average_temperature": 33.5333, + "experience_temperature": 27.5733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:30:06.852788+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 50.6, + "water_total": 0.0, + "average_temperature": 33.7667, + "experience_temperature": 27.7867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:40:06.586714+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.9, + "humidity": 49.9, + "water_total": 0.0, + "average_temperature": 34.0333, + "experience_temperature": 27.3133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T12:50:06.561976+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 49.0, + "water_total": 0.0, + "average_temperature": 34.0, + "experience_temperature": 27.7, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:00:05.642947+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.9, + "humidity": 49.2, + "water_total": 0.0, + "average_temperature": 34.0667, + "experience_temperature": 27.2067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:10:05.939939+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 47.4, + "water_total": 0.0, + "average_temperature": 33.9, + "experience_temperature": 27.28, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:20:06.701590+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 47.8, + "water_total": 0.0, + "average_temperature": 33.8, + "experience_temperature": 27.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:30:07.206417+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 48.6, + "water_total": 0.0, + "average_temperature": 33.5, + "experience_temperature": 27.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:40:06.565439+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 48.6, + "water_total": 0.0, + "average_temperature": 33.5, + "experience_temperature": 27.12, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T13:50:07.074665+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 44.1, + "water_total": 0.0, + "average_temperature": 34.5333, + "experience_temperature": 26.9533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T14:10:06.797266+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 43.2, + "water_total": 0.0, + "average_temperature": 34.4, + "experience_temperature": 27.24, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T14:20:07.561842+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 41.4, + "water_total": 0.0, + "average_temperature": 34.3333, + "experience_temperature": 26.5133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T14:30:06.272378+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 44.0, + "water_total": 0.0, + "average_temperature": 34.4, + "experience_temperature": 26.8, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T14:40:06.969526+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 42.6, + "water_total": 0.0, + "average_temperature": 34.1667, + "experience_temperature": 26.5867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T14:50:06.785321+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 41.8, + "water_total": 0.0, + "average_temperature": 33.8667, + "experience_temperature": 26.1267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T15:10:07.595250+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 44.4, + "water_total": 0.0, + "average_temperature": 33.1667, + "experience_temperature": 25.9467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T15:20:06.148320+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 45.1, + "water_total": 0.0, + "average_temperature": 33.2, + "experience_temperature": 25.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T15:30:08.549187+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 45.1, + "water_total": 0.0, + "average_temperature": 33.2, + "experience_temperature": 25.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T15:40:06.310039+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 46.0, + "water_total": 0.0, + "average_temperature": 33.2, + "experience_temperature": 26.3, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T15:50:05.650182+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.9, + "humidity": 43.3, + "water_total": 0.0, + "average_temperature": 33.0667, + "experience_temperature": 25.0267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T16:10:06.119001+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 78.9, + "water_total": 0.0, + "average_temperature": 28.1667, + "experience_temperature": 28.1467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T16:20:06.073968+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 47.7, + "water_total": 0.0, + "average_temperature": 32.1, + "experience_temperature": 25.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T16:30:06.273187+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 48.0, + "water_total": 0.0, + "average_temperature": 31.5333, + "experience_temperature": 25.3333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T16:40:06.708917+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 51.7, + "water_total": 0.0, + "average_temperature": 31.6667, + "experience_temperature": 25.9067, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T16:50:08.826924+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 55.4, + "water_total": 0.0, + "average_temperature": 31.5333, + "experience_temperature": 26.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T17:10:05.950105+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 63.9, + "water_total": 0.0, + "average_temperature": 30.2333, + "experience_temperature": 27.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T17:20:05.406041+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 65.4, + "water_total": 0.0, + "average_temperature": 30.2, + "experience_temperature": 26.88, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T17:30:06.515470+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 66.7, + "water_total": 0.0, + "average_temperature": 29.9, + "experience_temperature": 27.14, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T17:40:05.906615+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 68.2, + "water_total": 0.0, + "average_temperature": 29.6, + "experience_temperature": 26.84, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T17:50:05.836327+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 69.4, + "water_total": 0.0, + "average_temperature": 29.3667, + "experience_temperature": 26.8467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:00:06.487673+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 70.6, + "water_total": 0.0, + "average_temperature": 28.9667, + "experience_temperature": 26.6867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:10:07.028512+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 71.7, + "water_total": 0.0, + "average_temperature": 28.7, + "experience_temperature": 26.94, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:20:07.650857+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 72.3, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 26.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:30:06.479957+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 72.3, + "water_total": 0.0, + "average_temperature": 28.4667, + "experience_temperature": 26.5267, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:40:06.525084+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 72.8, + "water_total": 0.0, + "average_temperature": 28.3, + "experience_temperature": 26.76, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T18:50:07.007406+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 74.8, + "water_total": 0.0, + "average_temperature": 27.9333, + "experience_temperature": 26.7933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:00:06.633064+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 75.5, + "water_total": 0.0, + "average_temperature": 27.8667, + "experience_temperature": 26.8667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:10:06.518845+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 75.6, + "water_total": 0.0, + "average_temperature": 27.7, + "experience_temperature": 26.72, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:20:08.589867+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 76.0, + "water_total": 0.0, + "average_temperature": 27.6, + "experience_temperature": 26.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:30:06.263455+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 76.2, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 26.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:40:05.694115+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 76.2, + "water_total": 0.0, + "average_temperature": 27.4333, + "experience_temperature": 26.2733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T19:50:06.443538+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 76.6, + "water_total": 0.0, + "average_temperature": 27.3, + "experience_temperature": 26.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:00:06.590684+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 76.6, + "water_total": 0.0, + "average_temperature": 27.3, + "experience_temperature": 26.82, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:10:08.354348+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 26.4667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:20:07.141057+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 78.5, + "water_total": 0.0, + "average_temperature": 26.8667, + "experience_temperature": 26.4667, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:30:06.684929+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 80.1, + "water_total": 0.0, + "average_temperature": 26.4667, + "experience_temperature": 26.3867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:40:06.230506+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 80.6, + "water_total": 0.0, + "average_temperature": 26.3333, + "experience_temperature": 26.6533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T20:50:06.812680+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 81.0, + "water_total": 0.0, + "average_temperature": 26.2, + "experience_temperature": 26.0, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:00:12.592412+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 82.1, + "water_total": 0.0, + "average_temperature": 26.0667, + "experience_temperature": 26.0867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:10:09.685175+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 82.9, + "water_total": 0.0, + "average_temperature": 25.9667, + "experience_temperature": 26.7467, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:20:05.681628+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 83.4, + "water_total": 0.0, + "average_temperature": 25.8333, + "experience_temperature": 26.4133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:30:07.286984+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 84.0, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 26.4, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:40:07.029345+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 84.3, + "water_total": 0.0, + "average_temperature": 25.5333, + "experience_temperature": 26.2933, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T21:50:07.355124+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 84.4, + "water_total": 0.0, + "average_temperature": 25.4333, + "experience_temperature": 26.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:00:06.260246+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 84.4, + "water_total": 0.0, + "average_temperature": 25.4333, + "experience_temperature": 26.2133, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:10:05.537216+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 85.0, + "water_total": 0.0, + "average_temperature": 25.3333, + "experience_temperature": 26.2333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:20:05.964092+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 85.0, + "water_total": 0.0, + "average_temperature": 25.2, + "experience_temperature": 26.1, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:30:06.241111+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 85.6, + "water_total": 0.0, + "average_temperature": 25.0, + "experience_temperature": 26.02, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:40:06.984580+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 86.0, + "water_total": 0.0, + "average_temperature": 24.8333, + "experience_temperature": 25.9333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T22:50:07.142219+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 86.1, + "water_total": 0.0, + "average_temperature": 24.7667, + "experience_temperature": 25.8867, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:00:06.633385+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 85.7, + "water_total": 0.0, + "average_temperature": 24.7333, + "experience_temperature": 25.7733, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:10:07.230131+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.6, + "humidity": 85.0, + "water_total": 0.0, + "average_temperature": 24.5333, + "experience_temperature": 25.7333, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:20:07.613470+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 84.3, + "water_total": 0.0, + "average_temperature": 24.5, + "experience_temperature": 25.26, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:30:06.586759+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 83.6, + "water_total": 0.0, + "average_temperature": 24.4333, + "experience_temperature": 25.0533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:40:05.966598+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.8, + "humidity": 82.6, + "water_total": 0.0, + "average_temperature": 24.3333, + "experience_temperature": 24.4533, + "chill_factor": 3.0 + }, + { + "timestamp": "2026-07-09T23:50:07.002269+07:00", + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 82.0, + "water_total": 0.0, + "average_temperature": 24.2, + "experience_temperature": 24.5, + "chill_factor": 3.0 + } + ] +} diff --git a/scripts/iot_panel_cycle_extract.json b/scripts/iot_panel_cycle_extract.json new file mode 100644 index 0000000..f97019d --- /dev/null +++ b/scripts/iot_panel_cycle_extract.json @@ -0,0 +1,1105 @@ +{ + "cycle_start": "2026-05-22", + "cycle_end": "2026-07-09", + "experience_temperature": "avg_temp - (wind_speed * chill_factor - (humidity-70)/5); wind_speed is sensor m/s not fan count", + "flocks": [ + { + "name": "Lantai 1", + "iot_flock_id": "686df69f407b21002da8750c", + "source": "api", + "rows": [ + { + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 1667.0, + "average_temperature": 34.1667, + "experience_temperature": 20.1867, + "chill_factor": 8.0, + "cycle_day": 0 + }, + { + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 286.0, + "average_temperature": 34.2333, + "experience_temperature": 20.2333, + "chill_factor": 7.8333, + "cycle_day": 1 + }, + { + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 0.1, + "water_total": 3720.0, + "average_temperature": 33.0, + "experience_temperature": 19.02, + "chill_factor": 7.6667, + "cycle_day": 2 + }, + { + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 0.0, + "water_total": 9045.0, + "average_temperature": 32.3667, + "experience_temperature": 18.3667, + "chill_factor": 7.5, + "cycle_day": 3 + }, + { + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 681.0, + "average_temperature": 32.7333, + "experience_temperature": 35.9133, + "chill_factor": 7.3333, + "cycle_day": 4 + }, + { + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 79.9, + "water_total": 582.0, + "average_temperature": 31.5, + "experience_temperature": 33.48, + "chill_factor": 7.1667, + "cycle_day": 5 + }, + { + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 79.8, + "water_total": 1065.0, + "average_temperature": 30.4333, + "experience_temperature": 32.3933, + "chill_factor": 7.0, + "cycle_day": 6 + }, + { + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 83.1, + "water_total": 890.0, + "average_temperature": 30.1333, + "experience_temperature": 32.7533, + "chill_factor": 6.8571, + "cycle_day": 7 + }, + { + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 84.7, + "water_total": 10.0, + "average_temperature": 29.5667, + "experience_temperature": 32.5067, + "chill_factor": 6.7143, + "cycle_day": 8 + }, + { + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 83.7, + "water_total": 10.0, + "average_temperature": 29.3, + "experience_temperature": 32.04, + "chill_factor": 6.5714, + "cycle_day": 9 + }, + { + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 84.4, + "water_total": 1139.0, + "average_temperature": 29.1, + "experience_temperature": 31.98, + "chill_factor": 6.4286, + "cycle_day": 10 + }, + { + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.3, + "humidity": 82.9, + "water_total": 903.0, + "average_temperature": 29.4, + "experience_temperature": 30.0943, + "chill_factor": 6.2857, + "cycle_day": 11 + }, + { + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.2, + "humidity": 83.1, + "water_total": 1583.0, + "average_temperature": 29.8333, + "experience_temperature": 31.2248, + "chill_factor": 6.1429, + "cycle_day": 12 + }, + { + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.2, + "humidity": 86.2, + "water_total": 55.0, + "average_temperature": 29.2667, + "experience_temperature": 31.3067, + "chill_factor": 6.0, + "cycle_day": 13 + }, + { + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.2, + "humidity": 83.0, + "water_total": 23.0, + "average_temperature": 29.7667, + "experience_temperature": 31.2095, + "chill_factor": 5.7857, + "cycle_day": 14 + }, + { + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.1, + "humidity": 79.0, + "water_total": 2619.0, + "average_temperature": 29.3, + "experience_temperature": 30.5429, + "chill_factor": 5.5714, + "cycle_day": 15 + }, + { + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.1, + "humidity": 80.4, + "water_total": 1641.0, + "average_temperature": 28.9333, + "experience_temperature": 30.4776, + "chill_factor": 5.3571, + "cycle_day": 16 + }, + { + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.4, + "humidity": 82.6, + "water_total": 1831.0, + "average_temperature": 28.0333, + "experience_temperature": 28.4962, + "chill_factor": 5.1429, + "cycle_day": 17 + }, + { + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.7, + "humidity": 84.1, + "water_total": 1898.0, + "average_temperature": 27.8, + "experience_temperature": 27.17, + "chill_factor": 4.9286, + "cycle_day": 18 + }, + { + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.8, + "humidity": 84.9, + "water_total": 2159.0, + "average_temperature": 27.5, + "experience_temperature": 26.7086, + "chill_factor": 4.7143, + "cycle_day": 19 + }, + { + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.2, + "humidity": 84.3, + "water_total": 2092.0, + "average_temperature": 27.6333, + "experience_temperature": 25.0933, + "chill_factor": 4.5, + "cycle_day": 20 + }, + { + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.2, + "humidity": 82.5, + "water_total": 1995.0, + "average_temperature": 27.8333, + "experience_temperature": 25.1048, + "chill_factor": 4.3571, + "cycle_day": 21 + }, + { + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.2, + "humidity": 83.1, + "water_total": 1800.0, + "average_temperature": 27.7, + "experience_temperature": 25.2629, + "chill_factor": 4.2143, + "cycle_day": 22 + }, + { + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.2, + "humidity": 85.1, + "water_total": 1596.0, + "average_temperature": 27.9, + "experience_temperature": 26.0343, + "chill_factor": 4.0714, + "cycle_day": 23 + }, + { + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.2, + "humidity": 89.0, + "water_total": 7602.0, + "average_temperature": 25.9333, + "experience_temperature": 25.019, + "chill_factor": 3.9286, + "cycle_day": 24 + }, + { + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.1, + "humidity": 83.7, + "water_total": 1561.0, + "average_temperature": 26.8333, + "experience_temperature": 25.409, + "chill_factor": 3.7857, + "cycle_day": 25 + }, + { + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.6, + "humidity": 81.3, + "water_total": 1666.0, + "average_temperature": 27.5667, + "experience_temperature": 23.9981, + "chill_factor": 3.6429, + "cycle_day": 26 + }, + { + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.4, + "humidity": 84.4, + "water_total": 8274.0, + "average_temperature": 26.5667, + "experience_temperature": 24.5467, + "chill_factor": 3.5, + "cycle_day": 27 + }, + { + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.6, + "humidity": 85.3, + "water_total": 2091.0, + "average_temperature": 26.8333, + "experience_temperature": 24.2933, + "chill_factor": 3.5, + "cycle_day": 28 + }, + { + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.7, + "humidity": 87.8, + "water_total": 2370.0, + "average_temperature": 25.6, + "experience_temperature": 23.21, + "chill_factor": 3.5, + "cycle_day": 29 + }, + { + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.6, + "humidity": 89.7, + "water_total": 2477.0, + "average_temperature": 26.6, + "experience_temperature": 24.94, + "chill_factor": 3.5, + "cycle_day": 30 + }, + { + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.9, + "humidity": 88.6, + "water_total": 2221.0, + "average_temperature": 26.8, + "experience_temperature": 23.87, + "chill_factor": 3.5, + "cycle_day": 31 + }, + { + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.9, + "humidity": 89.0, + "water_total": 1370.0, + "average_temperature": 26.6333, + "experience_temperature": 23.7833, + "chill_factor": 3.5, + "cycle_day": 32 + }, + { + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.9, + "humidity": 90.5, + "water_total": 786.0, + "average_temperature": 26.7, + "experience_temperature": 24.15, + "chill_factor": 3.5, + "cycle_day": 33 + }, + { + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.3, + "humidity": 86.6, + "water_total": 549.0, + "average_temperature": 26.2, + "experience_temperature": 21.47, + "chill_factor": 3.5, + "cycle_day": 34 + }, + { + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.1, + "humidity": 90.2, + "water_total": 1247.0, + "average_temperature": 25.8333, + "experience_temperature": 26.1019, + "chill_factor": 3.4286, + "cycle_day": 35 + }, + { + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.8, + "humidity": 92.3, + "water_total": 4069.0, + "average_temperature": 26.6667, + "experience_temperature": 25.0838, + "chill_factor": 3.3571, + "cycle_day": 36 + }, + { + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.2, + "humidity": 90.9, + "water_total": 134.0, + "average_temperature": 25.3333, + "experience_temperature": 25.5705, + "chill_factor": 3.2857, + "cycle_day": 37 + }, + { + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.4, + "humidity": 88.2, + "water_total": 2050.0, + "average_temperature": 26.6, + "experience_temperature": 25.74, + "chill_factor": 3.2143, + "cycle_day": 38 + }, + { + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.6, + "humidity": 84.3, + "water_total": 148.0, + "average_temperature": 25.9, + "experience_temperature": 23.7314, + "chill_factor": 3.1429, + "cycle_day": 39 + }, + { + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.5, + "humidity": 86.8, + "water_total": 123.0, + "average_temperature": 25.5, + "experience_temperature": 24.2529, + "chill_factor": 3.0714, + "cycle_day": 40 + }, + { + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.6, + "humidity": 88.5, + "water_total": 193.0, + "average_temperature": 25.7333, + "experience_temperature": 24.6333, + "chill_factor": 3.0, + "cycle_day": 41 + }, + { + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.6, + "humidity": 84.9, + "water_total": 40.0, + "average_temperature": 26.5667, + "experience_temperature": 24.7467, + "chill_factor": 3.0, + "cycle_day": 42 + }, + { + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.6, + "humidity": 85.4, + "water_total": 0.0, + "average_temperature": 25.7333, + "experience_temperature": 24.0133, + "chill_factor": 3.0, + "cycle_day": 43 + }, + { + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.5, + "humidity": 87.3, + "water_total": 0.0, + "average_temperature": 25.8, + "experience_temperature": 24.76, + "chill_factor": 3.0, + "cycle_day": 44 + }, + { + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.7, + "humidity": 87.1, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 23.72, + "chill_factor": 3.0, + "cycle_day": 45 + }, + { + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.5, + "humidity": 88.9, + "water_total": 0.0, + "average_temperature": 25.3, + "experience_temperature": 24.58, + "chill_factor": 3.0, + "cycle_day": 46 + }, + { + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.4, + "humidity": 82.3, + "water_total": 0.0, + "average_temperature": 25.7, + "experience_temperature": 23.96, + "chill_factor": 3.0, + "cycle_day": 47 + }, + { + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.7, + "humidity": 82.0, + "water_total": 0.0, + "average_temperature": 24.2, + "experience_temperature": 24.5, + "chill_factor": 3.0, + "cycle_day": 48 + } + ] + }, + { + "name": "Lantai 2", + "iot_flock_id": "686df69f407b21002da8750d", + "source": "cloned_from_lantai_1", + "adjust": { + "wind_speed_delta": -0.05, + "humidity_delta": 1.2, + "average_temperature_delta": -0.3, + "water_total_factor": 0.96 + }, + "rows": [ + { + "date": "2026-05-22", + "age": 1, + "wind_speed": 0.0, + "humidity": 1.3, + "water_total": 1600.3, + "average_temperature": 33.8667, + "experience_temperature": 20.1267, + "chill_factor": 8.0, + "cycle_day": 0 + }, + { + "date": "2026-05-23", + "age": 2, + "wind_speed": 0.0, + "humidity": 1.2, + "water_total": 274.6, + "average_temperature": 33.9333, + "experience_temperature": 20.1733, + "chill_factor": 7.8333, + "cycle_day": 1 + }, + { + "date": "2026-05-24", + "age": 3, + "wind_speed": 0.0, + "humidity": 1.3, + "water_total": 3571.2, + "average_temperature": 32.7, + "experience_temperature": 18.96, + "chill_factor": 7.6667, + "cycle_day": 2 + }, + { + "date": "2026-05-25", + "age": 4, + "wind_speed": 0.0, + "humidity": 1.2, + "water_total": 8683.2, + "average_temperature": 32.0667, + "experience_temperature": 18.3067, + "chill_factor": 7.5, + "cycle_day": 3 + }, + { + "date": "2026-05-26", + "age": 5, + "wind_speed": 0.0, + "humidity": 87.1, + "water_total": 653.8, + "average_temperature": 32.4333, + "experience_temperature": 35.8533, + "chill_factor": 7.3333, + "cycle_day": 4 + }, + { + "date": "2026-05-27", + "age": 6, + "wind_speed": 0.0, + "humidity": 81.1, + "water_total": 558.7, + "average_temperature": 31.2, + "experience_temperature": 33.42, + "chill_factor": 7.1667, + "cycle_day": 5 + }, + { + "date": "2026-05-28", + "age": 7, + "wind_speed": 0.0, + "humidity": 81.0, + "water_total": 1022.4, + "average_temperature": 30.1333, + "experience_temperature": 32.3333, + "chill_factor": 7.0, + "cycle_day": 6 + }, + { + "date": "2026-05-29", + "age": 8, + "wind_speed": 0.0, + "humidity": 84.3, + "water_total": 854.4, + "average_temperature": 29.8333, + "experience_temperature": 32.6933, + "chill_factor": 6.8571, + "cycle_day": 7 + }, + { + "date": "2026-05-30", + "age": 9, + "wind_speed": 0.0, + "humidity": 85.9, + "water_total": 9.6, + "average_temperature": 29.2667, + "experience_temperature": 32.4467, + "chill_factor": 6.7143, + "cycle_day": 8 + }, + { + "date": "2026-05-31", + "age": 10, + "wind_speed": 0.0, + "humidity": 84.9, + "water_total": 9.6, + "average_temperature": 29.0, + "experience_temperature": 31.98, + "chill_factor": 6.5714, + "cycle_day": 9 + }, + { + "date": "2026-06-01", + "age": 11, + "wind_speed": 0.0, + "humidity": 85.6, + "water_total": 1093.4, + "average_temperature": 28.8, + "experience_temperature": 31.92, + "chill_factor": 6.4286, + "cycle_day": 10 + }, + { + "date": "2026-06-02", + "age": 12, + "wind_speed": 0.25, + "humidity": 84.1, + "water_total": 866.9, + "average_temperature": 29.1, + "experience_temperature": 30.3486, + "chill_factor": 6.2857, + "cycle_day": 11 + }, + { + "date": "2026-06-03", + "age": 13, + "wind_speed": 0.15, + "humidity": 84.3, + "water_total": 1519.7, + "average_temperature": 29.5333, + "experience_temperature": 31.4719, + "chill_factor": 6.1429, + "cycle_day": 12 + }, + { + "date": "2026-06-04", + "age": 14, + "wind_speed": 0.15, + "humidity": 87.4, + "water_total": 52.8, + "average_temperature": 28.9667, + "experience_temperature": 31.5467, + "chill_factor": 6.0, + "cycle_day": 13 + }, + { + "date": "2026-06-05", + "age": 15, + "wind_speed": 0.15, + "humidity": 84.2, + "water_total": 22.1, + "average_temperature": 29.4667, + "experience_temperature": 31.4388, + "chill_factor": 5.7857, + "cycle_day": 14 + }, + { + "date": "2026-06-06", + "age": 16, + "wind_speed": 0.05, + "humidity": 80.2, + "water_total": 2514.2, + "average_temperature": 29.0, + "experience_temperature": 30.7614, + "chill_factor": 5.5714, + "cycle_day": 15 + }, + { + "date": "2026-06-07", + "age": 17, + "wind_speed": 0.05, + "humidity": 81.6, + "water_total": 1575.4, + "average_temperature": 28.6333, + "experience_temperature": 30.6854, + "chill_factor": 5.3571, + "cycle_day": 16 + }, + { + "date": "2026-06-08", + "age": 18, + "wind_speed": 0.35, + "humidity": 83.8, + "water_total": 1757.8, + "average_temperature": 27.7333, + "experience_temperature": 28.6933, + "chill_factor": 5.1429, + "cycle_day": 17 + }, + { + "date": "2026-06-09", + "age": 19, + "wind_speed": 0.65, + "humidity": 85.3, + "water_total": 1822.1, + "average_temperature": 27.5, + "experience_temperature": 27.3564, + "chill_factor": 4.9286, + "cycle_day": 18 + }, + { + "date": "2026-06-10", + "age": 20, + "wind_speed": 0.75, + "humidity": 86.1, + "water_total": 2072.6, + "average_temperature": 27.2, + "experience_temperature": 26.8843, + "chill_factor": 4.7143, + "cycle_day": 19 + }, + { + "date": "2026-06-11", + "age": 21, + "wind_speed": 1.15, + "humidity": 85.5, + "water_total": 2008.3, + "average_temperature": 27.3333, + "experience_temperature": 25.2583, + "chill_factor": 4.5, + "cycle_day": 20 + }, + { + "date": "2026-06-12", + "age": 22, + "wind_speed": 1.15, + "humidity": 83.7, + "water_total": 1915.2, + "average_temperature": 27.5333, + "experience_temperature": 25.2626, + "chill_factor": 4.3571, + "cycle_day": 21 + }, + { + "date": "2026-06-13", + "age": 23, + "wind_speed": 1.15, + "humidity": 84.3, + "water_total": 1728.0, + "average_temperature": 27.4, + "experience_temperature": 25.4136, + "chill_factor": 4.2143, + "cycle_day": 22 + }, + { + "date": "2026-06-14", + "age": 24, + "wind_speed": 1.15, + "humidity": 86.3, + "water_total": 1532.2, + "average_temperature": 27.6, + "experience_temperature": 26.1779, + "chill_factor": 4.0714, + "cycle_day": 23 + }, + { + "date": "2026-06-15", + "age": 25, + "wind_speed": 1.15, + "humidity": 90.2, + "water_total": 7297.9, + "average_temperature": 25.6333, + "experience_temperature": 25.1554, + "chill_factor": 3.9286, + "cycle_day": 24 + }, + { + "date": "2026-06-16", + "age": 26, + "wind_speed": 1.05, + "humidity": 84.9, + "water_total": 1498.6, + "average_temperature": 26.5333, + "experience_temperature": 25.5383, + "chill_factor": 3.7857, + "cycle_day": 25 + }, + { + "date": "2026-06-17", + "age": 27, + "wind_speed": 1.55, + "humidity": 82.5, + "water_total": 1599.4, + "average_temperature": 27.2667, + "experience_temperature": 24.1203, + "chill_factor": 3.6429, + "cycle_day": 26 + }, + { + "date": "2026-06-18", + "age": 28, + "wind_speed": 1.35, + "humidity": 85.6, + "water_total": 7943.0, + "average_temperature": 26.2667, + "experience_temperature": 24.6617, + "chill_factor": 3.5, + "cycle_day": 27 + }, + { + "date": "2026-06-19", + "age": 29, + "wind_speed": 1.55, + "humidity": 86.5, + "water_total": 2007.4, + "average_temperature": 26.5333, + "experience_temperature": 24.4083, + "chill_factor": 3.5, + "cycle_day": 28 + }, + { + "date": "2026-06-20", + "age": 30, + "wind_speed": 1.65, + "humidity": 89.0, + "water_total": 2275.2, + "average_temperature": 25.3, + "experience_temperature": 23.325, + "chill_factor": 3.5, + "cycle_day": 29 + }, + { + "date": "2026-06-21", + "age": 31, + "wind_speed": 1.55, + "humidity": 90.9, + "water_total": 2377.9, + "average_temperature": 26.3, + "experience_temperature": 25.055, + "chill_factor": 3.5, + "cycle_day": 30 + }, + { + "date": "2026-06-22", + "age": 32, + "wind_speed": 1.85, + "humidity": 89.8, + "water_total": 2132.2, + "average_temperature": 26.5, + "experience_temperature": 23.985, + "chill_factor": 3.5, + "cycle_day": 31 + }, + { + "date": "2026-06-23", + "age": 33, + "wind_speed": 1.85, + "humidity": 90.2, + "water_total": 1315.2, + "average_temperature": 26.3333, + "experience_temperature": 23.8983, + "chill_factor": 3.5, + "cycle_day": 32 + }, + { + "date": "2026-06-24", + "age": 34, + "wind_speed": 1.85, + "humidity": 91.7, + "water_total": 754.6, + "average_temperature": 26.4, + "experience_temperature": 24.265, + "chill_factor": 3.5, + "cycle_day": 33 + }, + { + "date": "2026-06-25", + "age": 35, + "wind_speed": 2.25, + "humidity": 87.8, + "water_total": 527.0, + "average_temperature": 25.9, + "experience_temperature": 21.585, + "chill_factor": 3.5, + "cycle_day": 34 + }, + { + "date": "2026-06-26", + "age": 36, + "wind_speed": 1.05, + "humidity": 91.4, + "water_total": 1197.1, + "average_temperature": 25.5333, + "experience_temperature": 26.2133, + "chill_factor": 3.4286, + "cycle_day": 35 + }, + { + "date": "2026-06-27", + "age": 37, + "wind_speed": 1.75, + "humidity": 93.5, + "water_total": 3906.2, + "average_temperature": 26.3667, + "experience_temperature": 25.1917, + "chill_factor": 3.3571, + "cycle_day": 36 + }, + { + "date": "2026-06-28", + "age": 38, + "wind_speed": 1.15, + "humidity": 92.1, + "water_total": 128.6, + "average_temperature": 25.0333, + "experience_temperature": 25.6747, + "chill_factor": 3.2857, + "cycle_day": 37 + }, + { + "date": "2026-06-29", + "age": 39, + "wind_speed": 1.35, + "humidity": 89.4, + "water_total": 1968.0, + "average_temperature": 26.3, + "experience_temperature": 25.8407, + "chill_factor": 3.2143, + "cycle_day": 38 + }, + { + "date": "2026-06-30", + "age": 40, + "wind_speed": 1.55, + "humidity": 85.5, + "water_total": 142.1, + "average_temperature": 25.6, + "experience_temperature": 23.8286, + "chill_factor": 3.1429, + "cycle_day": 39 + }, + { + "date": "2026-07-01", + "age": 41, + "wind_speed": 1.45, + "humidity": 88.0, + "water_total": 118.1, + "average_temperature": 25.2, + "experience_temperature": 24.3464, + "chill_factor": 3.0714, + "cycle_day": 40 + }, + { + "date": "2026-07-02", + "age": 42, + "wind_speed": 1.55, + "humidity": 89.7, + "water_total": 185.3, + "average_temperature": 25.4333, + "experience_temperature": 24.7233, + "chill_factor": 3.0, + "cycle_day": 41 + }, + { + "date": "2026-07-03", + "age": 43, + "wind_speed": 1.55, + "humidity": 86.1, + "water_total": 38.4, + "average_temperature": 26.2667, + "experience_temperature": 24.8367, + "chill_factor": 3.0, + "cycle_day": 42 + }, + { + "date": "2026-07-04", + "age": 44, + "wind_speed": 1.55, + "humidity": 86.6, + "water_total": 0.0, + "average_temperature": 25.4333, + "experience_temperature": 24.1033, + "chill_factor": 3.0, + "cycle_day": 43 + }, + { + "date": "2026-07-05", + "age": 45, + "wind_speed": 1.45, + "humidity": 88.5, + "water_total": 0.0, + "average_temperature": 25.5, + "experience_temperature": 24.85, + "chill_factor": 3.0, + "cycle_day": 44 + }, + { + "date": "2026-07-06", + "age": 46, + "wind_speed": 1.65, + "humidity": 88.3, + "water_total": 0.0, + "average_temperature": 25.1, + "experience_temperature": 23.81, + "chill_factor": 3.0, + "cycle_day": 45 + }, + { + "date": "2026-07-07", + "age": 47, + "wind_speed": 1.45, + "humidity": 90.1, + "water_total": 0.0, + "average_temperature": 25.0, + "experience_temperature": 24.67, + "chill_factor": 3.0, + "cycle_day": 46 + }, + { + "date": "2026-07-08", + "age": 48, + "wind_speed": 1.35, + "humidity": 83.5, + "water_total": 0.0, + "average_temperature": 25.4, + "experience_temperature": 24.05, + "chill_factor": 3.0, + "cycle_day": 47 + }, + { + "date": "2026-07-09", + "age": 49, + "wind_speed": 0.65, + "humidity": 83.2, + "water_total": 0.0, + "average_temperature": 23.9, + "experience_temperature": 24.59, + "chill_factor": 3.0, + "cycle_day": 48 + } + ] + } + ] +} diff --git a/scripts/peek_xlsx.py b/scripts/peek_xlsx.py new file mode 100644 index 0000000..7995321 --- /dev/null +++ b/scripts/peek_xlsx.py @@ -0,0 +1,13 @@ +import openpyxl + +path = r"D:\DashboardCPSP\rework\dashboard-cpsp\backup\Laporan_Akhir-Siklus_Sukawarna_Kandang-Atas_Akhir-Siklus_2026-05-22_sd_2026-07-09.xlsx" + +wb = openpyxl.load_workbook(path, data_only=True) + +for sheet in ["Feed In", "Feed Use"]: + ws = wb[sheet] + print(f"\n===== SHEET: {sheet} =====") + for row in ws.iter_rows(): + vals = [(c.coordinate, c.value) for c in row if c.value is not None] + if vals: + print(vals) diff --git a/scripts/weigh_sample_count.py b/scripts/weigh_sample_count.py new file mode 100644 index 0000000..4bababb --- /dev/null +++ b/scripts/weigh_sample_count.py @@ -0,0 +1,21 @@ +"""Generate chicken_weight.chicken_count as weigh-sample size (not leftover birds).""" + +from __future__ import annotations + +import random + +# Deterministic: same cycle always gets the same sample sizes. +SAMPLE_RNG_SEED = 20260522 +SAMPLE_MIN = 180 +SAMPLE_MAX = 320 + + +def weigh_sample_count(*, average_weight: float, rng: random.Random | None = None) -> int: + """Birds used to compute that day's average_weight. + + 0 when there is no BW reading (age 38+ user decision). + """ + if average_weight is None or float(average_weight) <= 0: + return 0 + rng = rng or random.Random(SAMPLE_RNG_SEED) + return rng.randint(SAMPLE_MIN, SAMPLE_MAX) diff --git a/services/__tests__/apiClient.test.ts b/services/__tests__/apiClient.test.ts new file mode 100644 index 0000000..2cd09a8 --- /dev/null +++ b/services/__tests__/apiClient.test.ts @@ -0,0 +1,75 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { api, ApiError, errorMessage } from '../apiClient.ts'; + +const jsonResponse = (body: unknown, status = 200, headers: Record = {}) => + new Response(JSON.stringify(body), { + status, + headers: { 'Content-Type': 'application/json', ...headers }, + }); + +describe('apiClient', () => { + afterEach(() => { + vi.unstubAllGlobals(); + document.cookie = 'csrftoken=; Max-Age=0; path=/'; + }); + + it('unwraps paginated list results', async () => { + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue( + jsonResponse({ + count: 1, + next: null, + previous: null, + results: [{ id: 7, site_name: 'Sukawarna', user: 1 }], + }) + ) + ); + + const sites = await api.sites.list(); + expect(sites).toEqual([{ id: 7, site_name: 'Sukawarna', user: 1 }]); + }); + + it('unwraps a bare array list', async () => { + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue(jsonResponse([{ id: 2, site_name: 'Cilayang', user: 1 }])) + ); + + const sites = await api.sites.list(); + expect(sites[0]?.site_name).toBe('Cilayang'); + }); + + it('sends CSRF token on POST', async () => { + document.cookie = 'csrftoken=abc123; path=/'; + const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ id: 1, user_name: 'admin' })); + vi.stubGlobal('fetch', fetchMock); + + await api.auth.login('admin', 'admin123'); + + const init = fetchMock.mock.calls[0]?.[1] as RequestInit; + const headers = new Headers(init.headers); + expect(headers.get('X-CSRFToken')).toBe('abc123'); + expect(init.credentials).toBe('include'); + }); + + it('throws ApiError with detail and status', async () => { + document.cookie = 'csrftoken=abc123; path=/'; + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue(jsonResponse({ detail: 'Bad credentials' }, 400)) + ); + + await expect(api.auth.login('x', 'y')).rejects.toMatchObject({ + name: 'ApiError', + status: 400, + message: 'Bad credentials', + }); + }); + + it('maps unknown errors through errorMessage', () => { + expect(errorMessage(new ApiError('Gagal', 502, null))).toBe('Gagal'); + expect(errorMessage(new Error('boom'))).toBe('boom'); + expect(errorMessage('nope')).toBe('Terjadi kesalahan'); + }); +}); diff --git a/services/apiClient.ts b/services/apiClient.ts new file mode 100644 index 0000000..21f80a1 --- /dev/null +++ b/services/apiClient.ts @@ -0,0 +1,271 @@ +import type { + AIInsight, + ChickenCounting, + ChickenWeight, + CitySite, + CitySiteWrite, + CountingWrite, + Cycle, + CycleFilter, + CycleWrite, + Flock, + FlockWrite, + InitialBalanceResult, + Karung, + KarungRequestResult, + Kandang, + KandangWrite, + KPI, + LatestAvg, + ManualInput, + ManualInputWrite, + Paginated, + PanelIoT, + Site, + SiteWrite, + User, + UserWrite, +} from '../types/api.ts'; + +const API_BASE = (import.meta.env.VITE_API_BASE || '/api/v1').replace(/\/$/, ''); + +export const AUTH_UNAUTHORIZED_EVENT = 'dashboard-auth-unauthorized'; + +export class ApiError extends Error { + status: number; + body: unknown; + + constructor(message: string, status: number, body: unknown) { + super(message); + this.name = 'ApiError'; + this.status = status; + this.body = body; + } +} + +export function errorMessage(err: unknown): string { + if (err instanceof ApiError) return err.message; + if (err instanceof Error) return err.message; + return 'Terjadi kesalahan'; +} + +function getCookie(name: string): string | null { + const escaped = name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1'); + const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`)); + return match?.[1] ? decodeURIComponent(match[1]) : null; +} + +function parseDetail(body: unknown): string { + if (!body || typeof body !== 'object') return 'Request failed'; + const detail = (body as { detail?: unknown }).detail; + if (typeof detail === 'string') { + if (detail.toLowerCase().includes('csrf')) { + return 'Permintaan ditolak (CSRF). Muat ulang halaman lalu coba lagi.'; + } + return detail; + } + if (Array.isArray(detail)) return detail.map(String).join(', '); + const entries = Object.entries(body as Record) + .filter(([key]) => key !== 'detail') + .map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(', ') : String(value)}`); + return entries.length > 0 ? entries.join('; ') : 'Request failed'; +} + +async function ensureCsrf(): Promise { + const res = await fetch(`${API_BASE}/auth/csrf/`, { credentials: 'include' }); + if (!res.ok) { + throw new ApiError('Gagal mengambil CSRF token', res.status, null); + } + const data = (await res.json()) as { csrfToken?: string }; + return data.csrfToken || getCookie('csrftoken') || ''; +} + +function isCsrfFailure(status: number, body: unknown): boolean { + if (status !== 403) return false; + const detail = parseDetail(body).toLowerCase(); + return detail.includes('csrf'); +} + +type Query = Record; + +function withQuery(path: string, query?: Query): string { + if (!query) return path; + const params = new URLSearchParams(); + for (const [key, value] of Object.entries(query)) { + if (value === undefined || value === null || value === '') continue; + params.set(key, String(value)); + } + const qs = params.toString(); + return qs ? `${path}?${qs}` : path; +} + +async function request(path: string, init: RequestInit = {}, csrfRetried = false): Promise { + const method = (init.method || 'GET').toUpperCase(); + const headers = new Headers(init.headers); + headers.set('Accept', 'application/json'); + if (init.body && !headers.has('Content-Type')) { + headers.set('Content-Type', 'application/json'); + } + if (method !== 'GET' && method !== 'HEAD') { + const csrf = await ensureCsrf(); + if (csrf) headers.set('X-CSRFToken', csrf); + } + + const res = await fetch(`${API_BASE}${path}`, { + ...init, + method, + headers, + credentials: 'include', + }); + + if (res.status === 204) { + return undefined as T; + } + + const text = await res.text(); + let body: unknown = null; + if (text) { + try { + body = JSON.parse(text) as unknown; + } catch { + body = text; + } + } + + if (!res.ok) { + if (isCsrfFailure(res.status, body) && !csrfRetried && method !== 'GET' && method !== 'HEAD') { + return request(path, init, true); + } + if (res.status === 401) { + window.dispatchEvent(new CustomEvent(AUTH_UNAUTHORIZED_EVENT)); + } + throw new ApiError(parseDetail(body), res.status, body); + } + return body as T; +} + +function unwrapList(data: Paginated | T[]): T[] { + if (Array.isArray(data)) return data; + return data.results ?? []; +} + +const get = (path: string, query?: Query) => request(withQuery(path, query)); +const post = (path: string, body?: unknown) => + request(path, { method: 'POST', body: body !== undefined ? JSON.stringify(body) : undefined }); +const patch = (path: string, body: unknown) => + request(path, { method: 'PATCH', body: JSON.stringify(body) }); +const del = (path: string) => request(path, { method: 'DELETE' }); + +export const api = { + auth: { + csrf: () => get<{ csrfToken: string }>('/auth/csrf/'), + login: (user_name: string, password: string) => + post('/auth/login/', { user_name, password }), + logout: () => post('/auth/logout/'), + me: () => get('/auth/me/'), + }, + citySites: { + list: async () => unwrapList(await get | CitySite[]>('/city-sites/')), + create: (body: CitySiteWrite) => post('/city-sites/', body), + update: (id: number, body: Partial) => + patch(`/city-sites/${id}/`, body), + remove: (id: number) => del(`/city-sites/${id}/`), + }, + users: { + list: async () => unwrapList(await get | User[]>('/users/')), + create: (body: UserWrite) => post('/users/', body), + update: (id: number, body: Partial) => patch(`/users/${id}/`, body), + setPassword: (id: number, password: string) => + post(`/users/${id}/set-password/`, { password }), + listBuhs: async () => unwrapList(await get | User[]>('/users/buhs/')), + listPendingManaged: async () => + unwrapList(await get | User[]>('/users/pending-managed/')), + requestManagedBy: (buh_id: number) => + post('/users/request-managed-by/', { buh_id }), + cancelManagedByRequest: () => post('/users/cancel-managed-by-request/', {}), + approveManagedBy: (gmId: number) => post(`/users/${gmId}/approve-managed-by/`, {}), + rejectManagedBy: (gmId: number) => post(`/users/${gmId}/reject-managed-by/`, {}), + }, + sites: { + list: async (query?: { user_id?: number }) => + unwrapList(await get | Site[]>('/sites/', query)), + create: (body: SiteWrite) => post('/sites/', body), + update: (id: number, body: Partial) => patch(`/sites/${id}/`, body), + remove: (id: number) => del(`/sites/${id}/`), + }, + kandangs: { + list: async (query?: { site_id?: number }) => + unwrapList(await get | Kandang[]>('/kandangs/', query)), + create: (body: KandangWrite) => post('/kandangs/', body), + update: (id: number, body: Partial) => patch(`/kandangs/${id}/`, body), + remove: (id: number) => del(`/kandangs/${id}/`), + }, + flocks: { + list: async (query?: { kandang_id?: number }) => + unwrapList(await get | Flock[]>('/flocks/', query)), + create: (body: FlockWrite) => post('/flocks/', body), + update: (id: number, body: Partial) => patch(`/flocks/${id}/`, body), + remove: (id: number) => del(`/flocks/${id}/`), + }, + cycles: { + list: async (query?: CycleFilter) => + unwrapList(await get | Cycle[]>('/cycles/', query)), + create: (body: CycleWrite) => post('/cycles/', body), + update: (id: number, body: Partial) => patch(`/cycles/${id}/`, body), + remove: (id: number) => del(`/cycles/${id}/`), + initialBalance: (id: number, body: { date: string; feed_in_manual: number }) => + post(`/cycles/${id}/initial-balance/`, body), + initialBalanceCompare: ( + id: number, + query: { date: string; manual?: number } + ) => get(`/cycles/${id}/initial-balance-compare/`, query), + approveClose: (id: number) => + post(`/cycles/${id}/approve-close/`, {}), + rejectClose: (id: number) => + post(`/cycles/${id}/reject-close/`, {}), + }, + kpis: { + list: async (query?: CycleFilter) => + unwrapList(await get | KPI[]>('/kpis/', query)), + }, + manualInputs: { + list: async (query?: CycleFilter) => + unwrapList(await get | ManualInput[]>('/manual-inputs/', query)), + create: (body: ManualInputWrite) => post('/manual-inputs/', body), + update: (id: number, body: Partial) => + patch(`/manual-inputs/${id}/`, body), + }, + countings: { + list: async (query?: CycleFilter) => + unwrapList( + await get | ChickenCounting[]>('/chicken-countings/', query) + ), + create: (body: CountingWrite) => post('/chicken-countings/', body), + update: (id: number, body: Partial) => + patch(`/chicken-countings/${id}/`, body), + remove: (id: number) => del(`/chicken-countings/${id}/`), + sync: (body: { cycle_id: number }) => + post<{ upserted: number; dates: string[] }>('/chicken-countings/sync/', body), + }, + weights: { + list: async (query?: CycleFilter) => + unwrapList(await get | ChickenWeight[]>('/chicken-weights/', query)), + latestAvg: (query?: CycleFilter) => get('/chicken-weights/latest-avg/', query), + }, + karungs: { + list: async (query?: CycleFilter) => + unwrapList(await get | Karung[]>('/karungs/', query)), + latest: (query?: CycleFilter) => get('/karungs/latest/', query), + request: (body: { cycle_id: number; section?: 'today' | 'yesterday_history' }) => + post('/karungs/request/', body), + }, + panelIot: { + list: async (query?: CycleFilter) => + unwrapList(await get | PanelIoT[]>('/panel-iot/', query)), + dates: async (query?: CycleFilter) => get('/panel-iot/dates/', query), + }, + insights: { + list: async (query?: CycleFilter) => + unwrapList(await get | AIInsight[]>('/ai-insights/', query)), + }, +}; diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 0000000..117b3a6 --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,9 @@ +import { expect, afterEach } from 'vitest'; +import { cleanup } from '@testing-library/react'; +import * as matchers from '@testing-library/jest-dom/matchers'; + +expect.extend(matchers); + +afterEach(() => { + cleanup(); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..39182ce --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "isolatedModules": true, + "moduleDetection": "force", + "jsx": "react-jsx", + "noEmit": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "allowImportingTsExtensions": true, + "types": ["vite/client", "vitest/globals", "@testing-library/jest-dom", "node"], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["./**/*.ts", "./**/*.tsx"] +} diff --git a/types/api.ts b/types/api.ts new file mode 100644 index 0000000..5a25a4b --- /dev/null +++ b/types/api.ts @@ -0,0 +1,324 @@ +export type Paginated = { + count: number; + next: string | null; + previous: string | null; + results: T[]; +}; + +export type UserStatus = + | 'inactive' + | 'gm' + | 'gm_admin' + | 'buh' + | 'bu_admin' + | 'director' + | 'director_admin' + | 'account_admin' + | 'superuser'; + +export type User = { + id: number; + user_name: string; + status: UserStatus; + is_superuser?: boolean; + managed_by?: number | null; + managed_by_name?: string | null; + managed_by_pending?: number | null; + managed_by_pending_name?: string | null; + managed_by_requested_at?: string | null; + created_at: string; + updated_at: string; +}; + +export type UserWrite = { + user_name: string; + status: UserStatus; + password?: string; + managed_by?: number | null; +}; + +export type CitySite = { + id: number; + code: string; + name: string; + api_base_url: string; + has_api_key: boolean; + registered_by?: number | null; + registered_by_name?: string | null; + is_active: boolean; + last_synced_at: string | null; + last_sync_status: string; + last_sync_message: string; + created_at: string; + updated_at: string; +}; + +export type CitySiteWrite = { + code: string; + name: string; + api_base_url: string; + api_key?: string; + is_active?: boolean; +}; + +export type Site = { + id: number; + site_name: string; + user: number; + owner_name?: string; + city_site?: number | null; + created_at: string; + updated_at: string; +}; + +export type Kandang = { + id: number; + kandang_name: string; + site: number; + created_at: string; + updated_at: string; +}; + +export type Flock = { + id: number; + flock_name: string; + kandang: number; + created_at: string; + updated_at: string; +}; + +export type CycleStatus = 'active' | 'pending_close' | 'closed'; + +export type Cycle = { + id: number; + kandang: number; + kandang_name: string; + total_days: number; + current_day: number; + visible_through_date: string; + soft_end_date?: string; + start_date: string; + end_date: string | null; + chick_in_weight: number; + doc_in_count: number; + feed_initial_balance: number; + feed_initial_balance_date?: string | null; + status: CycleStatus; + city_site?: number | null; + source_cycle_id?: number | null; + proposed_end_date?: string | null; + close_requested_at?: string | null; + close_requested_by?: number | null; + close_approved_by?: number | null; + close_approved_at?: string | null; + created_at: string; + updated_at: string; +}; + +export type KPI = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + age: number; + mortality: number; + mortality_total: number; + feed: number; + feed_total: number; + harvest: number; + harvest_total: number; + harvest_weight: number; + harvest_weight_total: number; + chicken_life: number; + chicken_life_percentage: number; + iot_weight: number; + average_harvest_day: number; + average_harvest_weight: number; + fcr: number; + eef: number; + cc: number; + cw: number; + fs: number; + manual: number; + created_at: string; + updated_at: string; +}; + +export type ManualInput = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + age_manual: number; + mortality_manual: number; + mortality_manual_total: number; + feed_in_manual: number; + feed_use_manual: number; + feed_in_manual_total: number; + feed_use_manual_total: number; + feed_out_manual: number; + feed_out_manual_total: number; + harvest_manual: number; + harvest_manual_total: number; + harvest_weight_manual: number; + harvest_weight_manual_total: number; + manual_weight: number; + average_harvest_day_manual: number; + average_harvest_weight_manual: number; + fcr_manual: number; + eef_manual: number; + created_at: string; + updated_at: string; +}; + +export type ChickenCounting = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + total_count: number; + mortality_count: number; + created_at: string; + updated_at: string; +}; + +export type ChickenWeight = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + age: number; + doc_weight: number; + average_weight: number; + chicken_count: number; + uniformity: number; + average_daily_gain: number; + created_at: string; + updated_at: string; +}; + +export type LatestAvg = { + average_weight: number; + date: string; + age: number; + uniformity: number; + average_daily_gain: number; + cycle: number; + kandang: number; +}; + +export type Karung = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + in_today: number; + out_today: number; + in_total: number; + out_total: number; + feed_use_today: number; + feed_use_total: number; + created_at: string; + updated_at: string; +}; + +export type PanelIoT = { + id: number; + flock: number; + flock_id: number; + kandang: number | null; + date: string; + timestamp: string | null; + wind_speed: number; + humidity: number; + water_total: number; + average_temperature: number; + experience_temperature: number; + created_at: string; + updated_at: string; +}; + +export type AIInsight = { + id: number; + cycle: number; + kandang: number; + flock_id: number; + date: string; + insight_text: string; + alert: string; + section: string; + session: string; + created_at: string; + updated_at: string; +}; + +export type KarungRequestResult = { + karung: Karung; + upstream: Record; +}; + +export type CycleFilter = { + cycle_id?: number; + kandang_id?: number; + site_id?: number; + flock_id?: number; + date?: string; + status?: CycleStatus; +}; + +export type SiteWrite = { site_name: string; user: number }; +export type KandangWrite = { + kandang_name: string; + site: number; +}; +export type FlockWrite = { + flock_name: string; + kandang: number; +}; +export type CycleWrite = { + kandang: number; + total_days?: number; + current_day?: number; + start_date: string; + end_date?: string | null; + chick_in_weight: number; + doc_in_count: number; + feed_initial_balance?: number; + feed_initial_balance_date?: string | null; + status?: CycleStatus; +}; + +export type InitialBalanceResult = { + cycle: number; + date: string; + feed_initial_balance: number; + feed_initial_balance_date: string | null; + manual: number; + manual_total: number; + iot: number | null; + accuracy: number | null; + sync_error: string | null; +}; +export type CountingWrite = { + cycle: number; + date: string; + total_count?: number; + mortality_count?: number; +}; +export type ManualInputWrite = { + cycle: number; + date?: string; + age_manual?: number; + mortality_manual?: number; + feed_in_manual?: number; + feed_use_manual?: number; + feed_out_manual?: number; + harvest_manual?: number; + harvest_weight_manual?: number; + manual_weight?: number; +}; diff --git a/types/common.ts b/types/common.ts new file mode 100644 index 0000000..e6e779a --- /dev/null +++ b/types/common.ts @@ -0,0 +1,13 @@ +export type View = + | 'dashboard' + | 'dataManagement' + | 'weightMonitoring' + | 'weightStandard' + | 'feedSackCounting' + | 'cobbStandard' + | 'iotPanel' + | 'fcrDashboard' + | 'eefDashboard' + | 'kandangRanking' + | 'kandangSettings' + | 'userManagement'; diff --git a/types/dashboardReport.ts b/types/dashboardReport.ts new file mode 100644 index 0000000..ee2d57b --- /dev/null +++ b/types/dashboardReport.ts @@ -0,0 +1,86 @@ +export type ReportAccuracy = number | null; + +export type DashboardReportType = 'daily' | 'end_cycle'; + +export interface DashboardReportCountingRow { + date: string; + day: number; + countBefore: number | null; + mortality: number | null; + harvest: number | null; + harvestWeight: number | null; + countAfter: number | null; + iotCount: number | null; + accuracy: ReportAccuracy; +} + +export interface DashboardReportWeightRow { + date: string; + day: number; + avgManual: number | null; + avgIot: number | null; + uniformity: number | null; + difference: number | null; + accuracy: ReportAccuracy; +} + +export interface DashboardReportFeedInRow { + date: string; + manualIn: number | null; + iotIn: number | null; + accuracy: ReportAccuracy; +} + +export interface DashboardReportFeedUseRow { + date: string; + day: number; + manualUse: number | null; + iotUse: number | null; + accuracy: ReportAccuracy; +} + +export interface DashboardReportFeedOutRow { + date: string; + manualOut: number | null; + iotOut: number | null; + accuracy: ReportAccuracy; +} + +export interface DashboardReportFcrRow { + day: number; + iotFcr: number | null; + feedTotal: number | null; + iotWeight: number | null; + chickenLife: number | null; + harvestWeightTotal: number | null; +} + +export interface DashboardReportEefRow { + day: number; + iotEef: number | null; + chickenLifePercentage: number | null; + iotAverageHarvestBw: number | null; + iotAverageDayWeight: number | null; + iotFcr: number | null; +} + +export interface DashboardReportPayload { + cycleId: string; + cycleStart: string; + cycleEnd: string; + kandangId: number; + kandangName: string; + area: string; + upToDay: number; + /** DOC / chick-in weight in grams from cycle settings */ + docWeight: number | null; + generatedAt: string; + reportType: DashboardReportType; + counting: DashboardReportCountingRow[]; + weight: DashboardReportWeightRow[]; + feedIn: DashboardReportFeedInRow[]; + feedUse: DashboardReportFeedUseRow[]; + feedOut: DashboardReportFeedOutRow[]; + fcr: DashboardReportFcrRow[]; + eef: DashboardReportEefRow[]; +} diff --git a/utils/__tests__/buildInMemoryReport.test.ts b/utils/__tests__/buildInMemoryReport.test.ts new file mode 100644 index 0000000..d282eaf --- /dev/null +++ b/utils/__tests__/buildInMemoryReport.test.ts @@ -0,0 +1,180 @@ +import { describe, expect, it } from 'vitest'; +import { buildInMemoryReport } from '../buildInMemoryReport.ts'; +import type { ChickenCounting, Cycle, Karung, KPI } from '../../types/api.ts'; + +const cycle: Cycle = { + id: 1, + kandang: 9, + kandang_name: 'Kandang 1', + total_days: 35, + current_day: 1, + visible_through_date: '2026-05-02', + start_date: '2026-05-01', + end_date: '2026-06-04', + chick_in_weight: 45, + doc_in_count: 20000, + feed_initial_balance: 0, + status: 'gm', + created_at: '', + updated_at: '', +}; + +describe('buildInMemoryReport', () => { + it('maps IoT counting and karung onto daily rows up to current_day', () => { + const countings: ChickenCounting[] = [ + { + id: 1, + cycle: 1, + kandang: 9, + flock_id: 1, + date: '2026-05-02', + total_count: 19800, + mortality_count: 12, + created_at: '', + updated_at: '', + }, + ]; + const karungs: Karung[] = [ + { + id: 1, + cycle: 1, + kandang: 9, + flock_id: 1, + date: '2026-05-02', + in_today: 10, + out_today: 8, + in_total: 10, + out_total: 8, + feed_use_today: 8, + feed_use_total: 8, + created_at: '', + updated_at: '', + }, + ]; + const kpis: KPI[] = [ + { + id: 1, + cycle: 1, + kandang: 9, + flock_id: 1, + date: '2026-05-02', + age: 1, + mortality: 12, + mortality_total: 12, + feed: 8, + feed_total: 8, + harvest: 0, + harvest_total: 0, + harvest_weight: 0, + harvest_weight_total: 0, + chicken_life: 19800, + chicken_life_percentage: 99, + iot_weight: 0, + average_harvest_day: 0, + average_harvest_weight: 0, + fcr: 1.2, + eef: 250, + cc: 1, + cw: 1, + fs: 1, + manual: 1, + created_at: '', + updated_at: '', + }, + ]; + + const payload = buildInMemoryReport({ + cycle, + kandangId: 9, + kandangName: 'Kandang 1', + area: 'Sukawarna', + reportType: 'daily', + countings, + manuals: [], + weights: [], + karungs, + kpis, + }); + + expect(payload.upToDay).toBe(1); + expect(payload.docWeight).toBe(45); + expect(payload.counting).toHaveLength(2); + const day0 = payload.counting.find((row) => row.day === 0); + expect(day0?.countBefore).toBe(20000); + expect(day0?.countAfter).toBe(20000); + const day1 = payload.counting.find((row) => row.day === 1); + expect(day1?.countBefore).toBe(20000); + expect(day1?.iotCount).toBe(19800); + expect(day1?.mortality).toBe(12); + const feed1 = payload.feedUse.find((row) => row.day === 1); + expect(feed1?.iotUse).toBe(8); + expect(payload.fcr.find((row) => row.day === 1)?.iotFcr).toBe(1.2); + }); + + it('uses doc_in_count for day-0 stok awal instead of reverse-calculating from stok akhir', () => { + const countings: ChickenCounting[] = [ + { + id: 1, + cycle: 1, + kandang: 9, + flock_id: 1, + date: '2026-05-01', + total_count: 36900, + mortality_count: 42, + created_at: '', + updated_at: '', + }, + ]; + const kpis: KPI[] = [ + { + id: 1, + cycle: 1, + kandang: 9, + flock_id: 1, + date: '2026-05-01', + age: 0, + mortality: 42, + mortality_total: 42, + feed: 0, + feed_total: 0, + harvest: 0, + harvest_total: 0, + harvest_weight: 0, + harvest_weight_total: 0, + chicken_life: 45000, + chicken_life_percentage: 100, + iot_weight: 0, + average_harvest_day: 0, + average_harvest_weight: 0, + fcr: 0, + eef: 0, + cc: 1, + cw: 1, + fs: 1, + manual: 1, + created_at: '', + updated_at: '', + }, + ]; + + const payload = buildInMemoryReport({ + cycle: { ...cycle, doc_in_count: 45000, current_day: 0, start_date: '2026-05-01' }, + kandangId: 9, + kandangName: 'Kandang 1', + area: 'Sukawarna', + reportType: 'daily', + countings, + manuals: [], + weights: [], + karungs: [], + kpis, + }); + + const day0 = payload.counting.find((row) => row.day === 0); + expect(day0?.countBefore).toBe(45000); + expect(day0?.mortality).toBe(42); + expect(day0?.countAfter).toBe(45000); + expect(day0?.iotCount).toBe(36900); + expect(day0?.accuracy).toBe(82); + }); +}); diff --git a/utils/__tests__/countingAccuracyWarning.test.ts b/utils/__tests__/countingAccuracyWarning.test.ts new file mode 100644 index 0000000..022a9c4 --- /dev/null +++ b/utils/__tests__/countingAccuracyWarning.test.ts @@ -0,0 +1,217 @@ +import { describe, expect, it } from 'vitest'; +import type { ChickenCounting, Cycle, KPI, ManualInput } from '../../types/api.ts'; +import { getCountingAccuracyWarning } from '../countingAccuracyWarning.ts'; + +const cycle = { + id: 1, + kandang: 1, + kandang_name: 'K1', + total_days: 35, + current_day: 5, + visible_through_date: '2026-08-15', + start_date: '2026-08-10', + end_date: '2026-09-13', + chick_in_weight: 45, + doc_in_count: 1000, + feed_initial_balance: 0, + status: 'gm', + created_at: '', + updated_at: '', +} satisfies Cycle; + +function kpi(partial: Partial & Pick): KPI { + return { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + age: 0, + mortality: 0, + mortality_total: 0, + feed: 0, + feed_total: 0, + harvest: 0, + harvest_total: 0, + harvest_weight: 0, + harvest_weight_total: 0, + chicken_life_percentage: 100, + iot_weight: 0, + average_harvest_day: 0, + average_harvest_weight: 0, + fcr: 0, + eef: 0, + cc: 0, + cw: 0, + fs: 0, + manual: 0, + created_at: '', + updated_at: '', + ...partial, + }; +} + +function counting(partial: Partial & Pick): ChickenCounting { + return { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + mortality_count: 0, + created_at: '', + updated_at: '', + ...partial, + }; +} + +describe('getCountingAccuracyWarning', () => { + it('returns null when there is no IoT counting', () => { + expect( + getCountingAccuracyWarning({ + cycle, + countings: [], + kpis: [kpi({ date: '2026-08-10', chicken_life: 1000 })], + manualInputs: [], + }) + ).toBeNull(); + }); + + it('returns under when latest IoT is below stock and accuracy <= 95', () => { + const result = getCountingAccuracyWarning({ + cycle, + countings: [counting({ date: '2026-08-10', total_count: 930 })], + kpis: [kpi({ date: '2026-08-10', chicken_life: 1000 })], + manualInputs: [], + }); + expect(result).toMatchObject({ + day: 0, + date: '2026-08-10', + iotCount: 930, + stockAkhir: 1000, + direction: 'under', + }); + expect(result!.accuracy).toBe(93); + expect(result!.ratioPercent).toBe(93); + }); + + it('returns over when latest IoT is above stock and accuracy <= 95', () => { + // 1060/1000 → ratio 106%, accuracy min/max = 1000/1060 ≈ 94.3% + const result = getCountingAccuracyWarning({ + cycle, + countings: [counting({ date: '2026-08-10', total_count: 1060 })], + kpis: [kpi({ date: '2026-08-10', chicken_life: 1000 })], + manualInputs: [], + }); + expect(result).toMatchObject({ + day: 0, + iotCount: 1060, + stockAkhir: 1000, + direction: 'over', + }); + expect(result!.accuracy).toBe(94.3); + expect(result!.ratioPercent).toBe(106); + }); + + it('warns when accuracy is exactly 95', () => { + const result = getCountingAccuracyWarning({ + cycle, + countings: [counting({ date: '2026-08-10', total_count: 950 })], + kpis: [kpi({ date: '2026-08-10', chicken_life: 1000 })], + manualInputs: [], + }); + expect(result).toMatchObject({ accuracy: 95, direction: 'under' }); + }); + + it('returns null when accuracy is above 95', () => { + expect( + getCountingAccuracyWarning({ + cycle, + countings: [counting({ date: '2026-08-10', total_count: 960 })], + kpis: [kpi({ date: '2026-08-10', chicken_life: 1000 })], + manualInputs: [], + }) + ).toBeNull(); + }); + + it('uses the latest IoT day even if an older day is worse', () => { + const result = getCountingAccuracyWarning({ + cycle, + countings: [ + counting({ id: 1, date: '2026-08-10', total_count: 800 }), // worse under + counting({ id: 2, date: '2026-08-12', total_count: 970 }), // latest, accuracy 97% → no warn + ], + kpis: [ + kpi({ date: '2026-08-10', chicken_life: 1000 }), + kpi({ date: '2026-08-11', chicken_life: 1000 }), + kpi({ date: '2026-08-12', chicken_life: 1000 }), + ], + manualInputs: [], + }); + expect(result).toBeNull(); + }); + + it('warns from the latest IoT day when that day is low', () => { + const result = getCountingAccuracyWarning({ + cycle, + countings: [ + counting({ id: 1, date: '2026-08-10', total_count: 990 }), // fine + counting({ id: 2, date: '2026-08-12', total_count: 900 }), // latest under + ], + kpis: [ + kpi({ date: '2026-08-10', chicken_life: 1000 }), + kpi({ date: '2026-08-11', chicken_life: 1000 }), + kpi({ date: '2026-08-12', chicken_life: 1000 }), + ], + manualInputs: [], + }); + expect(result).toMatchObject({ + day: 2, + date: '2026-08-12', + iotCount: 900, + direction: 'under', + }); + }); + + it('derives stock akhir from chain when chicken_life is missing', () => { + const manuals: ManualInput[] = [ + { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-08-10', + age_manual: 0, + mortality_manual: 50, + mortality_manual_total: 50, + feed_in_manual: 0, + feed_use_manual: 0, + feed_in_manual_total: 0, + feed_use_manual_total: 0, + feed_out_manual: 0, + feed_out_manual_total: 0, + harvest_manual: 0, + harvest_manual_total: 0, + harvest_weight_manual: 0, + harvest_weight_manual_total: 0, + manual_weight: 0, + average_harvest_day_manual: 0, + average_harvest_weight_manual: 0, + fcr_manual: 0, + eef_manual: 0, + created_at: '', + updated_at: '', + }, + ]; + const result = getCountingAccuracyWarning({ + cycle, + countings: [counting({ date: '2026-08-10', total_count: 900 })], + kpis: [], + manualInputs: manuals, + }); + // stock = 1000 - 50 = 950; IoT 900 → under, accuracy 900/950 ≈ 94.7 + expect(result).toMatchObject({ + stockAkhir: 950, + iotCount: 900, + direction: 'under', + }); + }); +}); diff --git a/utils/__tests__/kandangRanking.test.ts b/utils/__tests__/kandangRanking.test.ts new file mode 100644 index 0000000..fd54e08 --- /dev/null +++ b/utils/__tests__/kandangRanking.test.ts @@ -0,0 +1,77 @@ +import { describe, expect, it } from 'vitest'; +import type { KPI } from '../../types/api.ts'; +import { + isEndDateInWindow, + latestValidRatios, + rankingWindowStart, +} from '../kandangRanking.ts'; + +function kpi(partial: Partial): KPI { + return { + id: 1, + cycle: 1, + kandang: 1, + flock_id: 1, + date: '2026-01-01', + age: 1, + mortality: 0, + mortality_total: 0, + feed: 0, + feed_total: 0, + harvest: 0, + harvest_total: 0, + harvest_weight: 0, + harvest_weight_total: 0, + chicken_life: 1000, + chicken_life_percentage: 100, + iot_weight: 0, + average_harvest_day: 0, + average_harvest_weight: 0, + fcr: 0, + eef: 0, + cc: 0, + cw: 0, + fs: 0, + manual: 0, + created_at: '', + updated_at: '', + ...partial, + }; +} + +describe('kandangRanking helpers', () => { + it('rankingWindowStart subtracts calendar months', () => { + expect(rankingWindowStart(3, new Date(2026, 8, 8))).toBe('2026-06-08'); + expect(rankingWindowStart(1, new Date(2026, 0, 31))).toBe('2025-12-31'); + }); + + it('isEndDateInWindow is inclusive on the lower bound', () => { + expect(isEndDateInWindow('2026-06-08', '2026-06-08')).toBe(true); + expect(isEndDateInWindow('2026-06-07', '2026-06-08')).toBe(false); + expect(isEndDateInWindow(null, '2026-06-08')).toBe(false); + }); + + it('latestValidRatios takes last positive EEF by age, not array order', () => { + // API-style newest-first ordering + const rows = [ + kpi({ date: '2026-01-03', age: 3, eef: 310, fcr: 1.25 }), + kpi({ date: '2026-01-02', age: 2, eef: 0, fcr: 1.3 }), + kpi({ date: '2026-01-01', age: 1, eef: 200, fcr: 1.4 }), + ]; + expect(latestValidRatios(rows)).toEqual({ eef: 310, fcr: 1.25 }); + }); + + it('latestValidRatios finds FCR and EEF independently from latest days', () => { + const rows = [ + kpi({ date: '2026-01-03', age: 3, eef: 320, fcr: 0 }), + kpi({ date: '2026-01-02', age: 2, eef: 0, fcr: 1.22 }), + kpi({ date: '2026-01-01', age: 1, eef: 100, fcr: 1.5 }), + ]; + expect(latestValidRatios(rows)).toEqual({ eef: 320, fcr: 1.22 }); + }); + + it('latestValidRatios returns null EEF when none valid', () => { + const rows = [kpi({ age: 2, eef: 0, fcr: 1.2 }), kpi({ age: 1, eef: 0, fcr: 0 })]; + expect(latestValidRatios(rows)).toEqual({ eef: null, fcr: 1.2 }); + }); +}); diff --git a/utils/__tests__/reportSummary.test.ts b/utils/__tests__/reportSummary.test.ts new file mode 100644 index 0000000..c3bf4c7 --- /dev/null +++ b/utils/__tests__/reportSummary.test.ts @@ -0,0 +1,220 @@ +import { describe, expect, it } from 'vitest'; +import { buildReportSummary, latestValidRatio } from '../reportSummary.ts'; +import type { ReportSummaryMetric, ReportSummaryMetricKey } from '../reportSummary.ts'; +import type { DashboardReportPayload } from '../../types/dashboardReport.ts'; + +function emptyPayload(overrides: Partial = {}): DashboardReportPayload { + return { + cycleId: '1', + cycleStart: '2026-05-01', + cycleEnd: '2026-06-04', + kandangId: 9, + kandangName: 'Kandang 1', + area: 'Area A', + upToDay: 2, + docWeight: null, + generatedAt: '2026-05-03T00:00:00.000Z', + reportType: 'daily', + counting: [], + weight: [], + feedIn: [], + feedUse: [], + feedOut: [], + fcr: [], + eef: [], + ...overrides, + }; +} + +describe('latestValidRatio', () => { + it('returns the last finite value walking backward', () => { + expect( + latestValidRatio( + [ + { iotFcr: 1.1 }, + { iotFcr: null }, + { iotFcr: 1.4 }, + { iotFcr: null }, + ], + 'iotFcr' + ) + ).toBe(1.4); + }); + + it('returns null when no finite values exist', () => { + expect(latestValidRatio([{ iotEef: null }, { iotEef: null }], 'iotEef')).toBeNull(); + }); +}); + +describe('buildReportSummary', () => { + it('returns 14 metrics in the agreed order with nulls when sections are empty', () => { + const summary = buildReportSummary(emptyPayload({ upToDay: 5 })); + expect(summary.metrics.map((m) => m.key)).toEqual([ + 'umur', + 'docWeight', + 'populasi', + 'mortalitas', + 'panen', + 'beratPanen', + 'karungMasuk', + 'karungDituang', + 'beratPakan', + 'karungKeluar', + 'beratAvg', + 'uniformity', + 'fcr', + 'eef', + ]); + expect(summary.metrics[0]).toMatchObject({ label: 'Umur', value: 5, unit: 'hari' }); + expect(summary.metrics.slice(1).every((m) => m.value === null)).toBe(true); + }); + + it('derives totals, latest populasi/weight, and FCR/EEF from payload rows', () => { + const summary = buildReportSummary( + emptyPayload({ + upToDay: 2, + counting: [ + { + date: '2026-05-01', + day: 0, + countBefore: 20000, + mortality: 10, + harvest: 0, + harvestWeight: 0, + countAfter: 19990, + iotCount: null, + accuracy: null, + }, + { + date: '2026-05-03', + day: 2, + countBefore: 19980, + mortality: 5, + harvest: 100, + harvestWeight: 150000, + countAfter: 19875, + iotCount: 19870, + accuracy: 99.9, + }, + ], + weight: [ + { + date: '2026-05-01', + day: 0, + avgManual: 45, + avgIot: 46, + uniformity: 80, + difference: 1, + accuracy: 97, + }, + { + date: '2026-05-03', + day: 2, + avgManual: 900, + avgIot: 910, + uniformity: 88.5, + difference: 10, + accuracy: 98, + }, + ], + feedIn: [ + { date: '2026-05-01', manualIn: 20, iotIn: 21, accuracy: 95 }, + { date: '2026-05-03', manualIn: 10, iotIn: 10, accuracy: 100 }, + ], + feedUse: [ + { date: '2026-05-01', day: 0, manualUse: 8, iotUse: 8, accuracy: 100 }, + { date: '2026-05-03', day: 2, manualUse: 12, iotUse: 11, accuracy: 91 }, + ], + feedOut: [ + { date: '2026-05-01', manualOut: 1, iotOut: 1, accuracy: 100 }, + { date: '2026-05-03', manualOut: 2, iotOut: 2, accuracy: 100 }, + ], + fcr: [ + { + day: 0, + iotFcr: 0.5, + feedTotal: 1, + iotWeight: 46, + chickenLife: 19990, + harvestWeightTotal: 0, + }, + { + day: 2, + iotFcr: 1.25, + feedTotal: 20, + iotWeight: 910, + chickenLife: 19875, + harvestWeightTotal: 150, + }, + ], + eef: [ + { + day: 0, + iotEef: 100, + chickenLifePercentage: 99.9, + iotAverageHarvestBw: null, + iotAverageDayWeight: 46, + iotFcr: 0.5, + }, + { + day: 2, + iotEef: 320, + chickenLifePercentage: 99.4, + iotAverageHarvestBw: 1500, + iotAverageDayWeight: 910, + iotFcr: 1.25, + }, + ], + }) + ); + + const byKey = Object.fromEntries(summary.metrics.map((m) => [m.key, m])) as Record< + ReportSummaryMetricKey, + ReportSummaryMetric + >; + expect(byKey.umur.value).toBe(2); + expect(byKey.docWeight.value).toBeNull(); + expect(byKey.populasi.value).toBe(19875); + expect(byKey.mortalitas.value).toBe(15); + expect(byKey.panen.value).toBe(100); + expect(byKey.beratPanen.value).toBe(150); + expect(byKey.karungMasuk.value).toBe(30); + expect(byKey.karungDituang.value).toBe(20); + expect(byKey.beratPakan.value).toBe(1000); + expect(byKey.karungKeluar.value).toBe(3); + expect(byKey.beratAvg.value).toBe(910); + expect(byKey.uniformity.value).toBe(88.5); + expect(byKey.fcr.value).toBe(1.25); + expect(byKey.eef.value).toBe(320); + }); + + it('falls back to avgManual when avgIot is null on the latest weight row', () => { + const summary = buildReportSummary( + emptyPayload({ + weight: [ + { + date: '2026-05-03', + day: 2, + avgManual: 905, + avgIot: null, + uniformity: 90, + difference: null, + accuracy: null, + }, + ], + }) + ); + expect(summary.metrics.find((m) => m.key === 'beratAvg')?.value).toBe(905); + }); + + it('places Berat DOC beside Umur from payload.docWeight', () => { + const summary = buildReportSummary(emptyPayload({ upToDay: 3, docWeight: 42 })); + expect(summary.metrics[0]).toMatchObject({ key: 'umur', value: 3 }); + expect(summary.metrics[1]).toMatchObject({ + key: 'docWeight', + label: 'Berat DOC', + value: 42, + unit: 'gram', + }); + }); +}); diff --git a/utils/__tests__/visibility.test.ts b/utils/__tests__/visibility.test.ts new file mode 100644 index 0000000..ebc630e --- /dev/null +++ b/utils/__tests__/visibility.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from 'vitest'; +import { isOnOrBeforeVisibleDate, throughVisibleDate } from '../visibility.ts'; + +describe('throughVisibleDate', () => { + const rows = [{ date: '2026-09-05' }, { date: '2026-09-06' }, { date: '2026-09-07' }]; + + it('drops rows after the publish cutoff', () => { + expect(throughVisibleDate(rows, '2026-09-06')).toEqual([ + { date: '2026-09-05' }, + { date: '2026-09-06' }, + ]); + }); + + it('returns all rows when cutoff is missing', () => { + expect(throughVisibleDate(rows, undefined)).toEqual(rows); + expect(throughVisibleDate(rows, null)).toEqual(rows); + }); +}); + +describe('isOnOrBeforeVisibleDate', () => { + it('rejects dates after the cutoff', () => { + expect(isOnOrBeforeVisibleDate('2026-09-07', '2026-09-06')).toBe(false); + }); + + it('accepts dates on or before the cutoff', () => { + expect(isOnOrBeforeVisibleDate('2026-09-06', '2026-09-06')).toBe(true); + expect(isOnOrBeforeVisibleDate('2026-09-05', '2026-09-06')).toBe(true); + }); + + it('rejects empty dates', () => { + expect(isOnOrBeforeVisibleDate(null, '2026-09-06')).toBe(false); + expect(isOnOrBeforeVisibleDate(undefined, '2026-09-06')).toBe(false); + }); +}); diff --git a/utils/__tests__/weight.test.ts b/utils/__tests__/weight.test.ts new file mode 100644 index 0000000..db2f677 --- /dev/null +++ b/utils/__tests__/weight.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'vitest'; +import { weightStandardData } from '../../mockData/weightStandardData.ts'; +import { getTargetGainForAge, getTargetWeightForAge } from '../weight.ts'; + +function rowForDoc(docWeight: number) { + return weightStandardData.data.find((row) => row.day === docWeight)!; +} + +describe('getTargetWeightForAge', () => { + it('uses the exact DOC-weight row and age column', () => { + const row = rowForDoc(42); + expect(getTargetWeightForAge(1, 42)).toBe(row.values[0]); + expect(getTargetWeightForAge(35, 42)).toBe(row.values[34]); + }); + + it('clamps below-range DOC weight to the 35 g row', () => { + const row = rowForDoc(35); + expect(getTargetWeightForAge(7, 20)).toBe(row.values[6]); + expect(getTargetWeightForAge(7, 30)).toBe(row.values[6]); + }); + + it('clamps above-range DOC weight to the 51 g row', () => { + const row = rowForDoc(51); + expect(getTargetWeightForAge(7, 52)).toBe(row.values[6]); + expect(getTargetWeightForAge(7, 60)).toBe(row.values[6]); + }); + + it('returns null for ages outside 1..35', () => { + expect(getTargetWeightForAge(0, 42)).toBeNull(); + expect(getTargetWeightForAge(36, 42)).toBeNull(); + }); +}); + +describe('getTargetGainForAge', () => { + it('returns day-over-day delta from the DOC-weight row', () => { + const row = rowForDoc(40); + expect(getTargetGainForAge(2, 40)).toBe(row.values[1]! - row.values[0]!); + }); + + it('returns null for age 1', () => { + expect(getTargetGainForAge(1, 40)).toBeNull(); + }); +}); diff --git a/utils/buildInMemoryReport.ts b/utils/buildInMemoryReport.ts new file mode 100644 index 0000000..590173e --- /dev/null +++ b/utils/buildInMemoryReport.ts @@ -0,0 +1,231 @@ +import type { + ChickenCounting, + ChickenWeight, + Cycle, + Karung, + KPI, + ManualInput, +} from '../types/api.ts'; +import type { DashboardReportPayload, DashboardReportType } from '../types/dashboardReport.ts'; +import { cycleDayForDate } from './format.ts'; + +export type BuildInMemoryReportInput = { + cycle: Cycle; + kandangId: number; + kandangName: string; + area: string; + reportType: DashboardReportType; + countings: ChickenCounting[]; + manuals: ManualInput[]; + weights: ChickenWeight[]; + karungs: Karung[]; + kpis: KPI[]; + generatedAt?: string; + /** Override the report's last day (0-based); defaults to current day / cycle end. */ + upToDay?: number; +}; + +function accuracy(iot: number | null, manual: number | null): number | null { + if (iot == null || manual == null || manual === 0) return null; + return Math.round((1 - Math.abs(iot - manual) / Math.abs(manual)) * 1000) / 10; +} + +function countingAccuracy(iot: number | null, stockAkhir: number | null): number | null { + if (iot == null || stockAkhir == null || stockAkhir <= 0) return null; + return Math.round((Math.min(iot, stockAkhir) / Math.max(iot, stockAkhir)) * 1000) / 10; +} + +/** Feed accuracy: both manual and IoT reading zero means a perfect match (100%); + * if only one side has a reading, the match is 0%. */ +function feedAccuracy(iot: number | null, manual: number | null): number | null { + if (manual != null && iot != null) { + if (manual === 0 && iot === 0) return 100; + if (manual === 0 || iot === 0) return 0; + } + return accuracy(iot, manual); +} + +export function buildInMemoryReport(input: BuildInMemoryReportInput): DashboardReportPayload { + const { cycle } = input; + // Day numbering stays 0-based (day 0 = start_date), but the report must never + // run past the cycle end date. lastDay = start_date → end_date in days, which + // is total_days - 1 for a contiguous cycle. + const lastDay = cycleDayForDate(cycle.start_date, cycle.end_date); + const endCycleUpTo = Math.min(cycle.total_days, lastDay); + const defaultUpTo = + input.reportType === 'end_cycle' + ? endCycleUpTo + : Math.min(Math.max(cycle.current_day, 0), lastDay); + const upToDay = + input.upToDay != null && Number.isFinite(input.upToDay) + ? Math.min(Math.max(Math.floor(input.upToDay), 0), lastDay) + : defaultUpTo; + const days = Array.from({ length: Math.max(upToDay, 0) + 1 }, (_, day) => day); + + const countingByDay = new Map(); + for (const row of input.countings) { + countingByDay.set(cycleDayForDate(cycle.start_date, row.date), row); + } + const weightByDay = new Map(); + for (const row of input.weights) { + weightByDay.set(cycleDayForDate(cycle.start_date, row.date), row); + } + const karungByDay = new Map(); + for (const row of input.karungs) { + karungByDay.set(cycleDayForDate(cycle.start_date, row.date), row); + } + const kpiByAge = new Map(); + for (const row of input.kpis) { + kpiByAge.set(row.age, row); + } + const manualByDay = new Map(); + for (const row of input.manuals) { + manualByDay.set(cycleDayForDate(cycle.start_date, row.date), row); + } + const manualWeightByDay = new Map(); + const manualFeedInByDay = new Map(); + const manualFeedUseByDay = new Map(); + const manualFeedOutByDay = new Map(); + for (const row of input.manuals) { + const day = cycleDayForDate(cycle.start_date, row.date); + if (row.manual_weight > 0) manualWeightByDay.set(day, row.manual_weight); + manualFeedInByDay.set(day, row.feed_in_manual); + manualFeedUseByDay.set(day, row.feed_use_manual); + manualFeedOutByDay.set(day, row.feed_out_manual); + } + let previousStockAkhir: number | null = null; + const counting = days.map((day) => { + const iot = countingByDay.get(day) ?? null; + const kpi = kpiByAge.get(day) ?? null; + const manual = manualByDay.get(day) ?? null; + const iotCount = iot?.total_count ?? null; + const mortality = + manual?.mortality_manual ?? kpi?.mortality ?? iot?.mortality_count ?? null; + const harvest = manual?.harvest_manual ?? kpi?.harvest ?? null; + const harvestWeight = manual?.harvest_weight_manual ?? kpi?.harvest_weight ?? null; + const mati = mortality ?? 0; + const panen = harvest ?? 0; + const countBefore = day === 0 ? cycle.doc_in_count || 0 : (previousStockAkhir ?? 0); + const countAfter = kpi?.chicken_life ?? Math.max(0, countBefore - mati - panen); + previousStockAkhir = countAfter; + + return { + date: addDate(cycle.start_date, day), + day, + countBefore, + mortality, + harvest, + harvestWeight, + countAfter, + iotCount, + accuracy: countingAccuracy(iotCount, countAfter), + }; + }); + + const weight = days.map((day) => { + const iot = weightByDay.get(day) ?? null; + const avgIot = iot?.average_weight ?? null; + const avgManual = manualWeightByDay.get(day) ?? null; + return { + date: addDate(cycle.start_date, day), + day, + avgManual, + avgIot, + uniformity: iot?.uniformity ?? null, + difference: avgIot != null && avgManual != null ? avgIot - avgManual : null, + accuracy: accuracy(avgIot, avgManual), + }; + }); + + const feedIn = days.map((day) => { + const karung = karungByDay.get(day) ?? null; + const iotIn = karung?.in_today ?? null; + const manualIn = manualFeedInByDay.get(day) ?? null; + return { + date: addDate(cycle.start_date, day), + manualIn, + iotIn, + accuracy: feedAccuracy(iotIn, manualIn), + }; + }); + + const feedUse = days.map((day) => { + const karung = karungByDay.get(day) ?? null; + const iotUse = karung?.feed_use_today ?? karung?.out_today ?? null; + const manualUse = manualFeedUseByDay.get(day) ?? null; + return { + date: addDate(cycle.start_date, day), + day, + manualUse, + iotUse, + accuracy: feedAccuracy(iotUse, manualUse), + }; + }); + + const feedOut = days.map((day) => { + const karung = karungByDay.get(day) ?? null; + const iotOut = karung?.out_today ?? null; + const manualOut = manualFeedOutByDay.get(day) ?? null; + return { + date: addDate(cycle.start_date, day), + manualOut, + iotOut, + accuracy: feedAccuracy(iotOut, manualOut), + }; + }); + + const fcr = days.map((day) => { + const kpi = kpiByAge.get(day) ?? null; + const weightRow = weightByDay.get(day) ?? null; + return { + day, + iotFcr: kpi?.fcr ?? null, + feedTotal: kpi?.feed_total ?? null, + iotWeight: weightRow?.average_weight ?? kpi?.iot_weight ?? null, + chickenLife: kpi?.chicken_life ?? null, + harvestWeightTotal: kpi?.harvest_weight_total ?? null, + }; + }); + + const eef = days.map((day) => { + const kpi = kpiByAge.get(day) ?? null; + return { + day, + iotEef: kpi?.eef ?? null, + chickenLifePercentage: kpi?.chicken_life_percentage ?? null, + iotAverageHarvestBw: kpi?.average_harvest_weight ?? null, + iotAverageDayWeight: kpi?.iot_weight ?? null, + iotFcr: kpi?.fcr ?? null, + }; + }); + + return { + cycleId: String(cycle.id), + cycleStart: cycle.start_date, + cycleEnd: cycle.end_date, + kandangId: input.kandangId, + kandangName: input.kandangName, + area: input.area, + upToDay, + docWeight: + typeof cycle.chick_in_weight === 'number' && Number.isFinite(cycle.chick_in_weight) + ? cycle.chick_in_weight + : null, + generatedAt: input.generatedAt ?? new Date().toISOString(), + reportType: input.reportType, + counting, + weight, + feedIn, + feedUse, + feedOut, + fcr, + eef, + }; +} + +function addDate(start: string, day: number): string { + const date = new Date(`${start}T00:00:00`); + date.setDate(date.getDate() + day); + const pad = (n: number) => String(n).padStart(2, '0'); + return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; +} diff --git a/utils/countingAccuracyWarning.ts b/utils/countingAccuracyWarning.ts new file mode 100644 index 0000000..da83dc6 --- /dev/null +++ b/utils/countingAccuracyWarning.ts @@ -0,0 +1,96 @@ +import type { ChickenCounting, Cycle, KPI, ManualInput } from '../types/api.ts'; +import { addDaysIso, cycleDayForDate } from './format.ts'; + +export const COUNTING_ACCURACY_WARNING_THRESHOLD = 95; + +export type CountingAccuracyWarning = { + day: number; + date: string; + iotCount: number; + stockAkhir: number; + accuracy: number; + ratioPercent: number; + direction: 'over' | 'under'; +}; + +export type CountingAccuracyWarningInput = { + cycle: Pick; + countings: ChickenCounting[]; + kpis: KPI[]; + manualInputs: ManualInput[]; +}; + +function round1(value: number): number { + return Math.round(value * 10) / 10; +} + +function matchAccuracy(iot: number, stockAkhir: number): number { + return round1((Math.min(iot, stockAkhir) / Math.max(iot, stockAkhir)) * 100); +} + +/** Build stock-akhir by date using the same rules as Hitung Ayam. */ +function stockAkhirByDate( + cycle: CountingAccuracyWarningInput['cycle'], + kpis: KPI[], + manualInputs: ManualInput[] +): Map { + const kpiByDate = new Map(kpis.map((k) => [k.date, k])); + const manualByDate = new Map(manualInputs.map((m) => [m.date, m])); + + const lastCycleDay = Math.max(0, (cycle.total_days || 1) - 1); + const endDay = cycleDayForDate(cycle.start_date, cycle.end_date); + const maxDay = Math.min(lastCycleDay, endDay); + + const result = new Map(); + let previousStockAkhir = 0; + + for (let day = 0; day <= maxDay; day++) { + const date = addDaysIso(cycle.start_date, day); + const kpi = kpiByDate.get(date); + const manual = manualByDate.get(date); + const stockAwal = day === 0 ? cycle.doc_in_count || 0 : previousStockAkhir; + const mati = manual?.mortality_manual ?? kpi?.mortality ?? 0; + const panen = manual?.harvest_manual ?? kpi?.harvest ?? 0; + const stockAkhir = kpi?.chicken_life ?? Math.max(0, stockAwal - mati - panen); + result.set(date, stockAkhir); + previousStockAkhir = stockAkhir; + } + + return result; +} + +function latestIotCounting(countings: ChickenCounting[]): ChickenCounting | null { + let best: ChickenCounting | null = null; + for (const row of countings) { + if (row.total_count == null) continue; + if (!best || row.date > best.date) best = row; + } + return best; +} + +export function getCountingAccuracyWarning( + input: CountingAccuracyWarningInput +): CountingAccuracyWarning | null { + const latest = latestIotCounting(input.countings); + if (!latest) return null; + + const stockMap = stockAkhirByDate(input.cycle, input.kpis, input.manualInputs); + const stockAkhir = stockMap.get(latest.date); + if (stockAkhir == null || stockAkhir <= 0) return null; + + const iotCount = latest.total_count; + if (iotCount === stockAkhir) return null; + + const accuracy = matchAccuracy(iotCount, stockAkhir); + if (accuracy > COUNTING_ACCURACY_WARNING_THRESHOLD) return null; + + return { + day: cycleDayForDate(input.cycle.start_date, latest.date), + date: latest.date, + iotCount, + stockAkhir, + accuracy, + ratioPercent: round1((iotCount / stockAkhir) * 100), + direction: iotCount > stockAkhir ? 'over' : 'under', + }; +} diff --git a/utils/format.ts b/utils/format.ts new file mode 100644 index 0000000..ba93b65 --- /dev/null +++ b/utils/format.ts @@ -0,0 +1,74 @@ +export function formatNumber( + value: number, + maxDecimals = 2, + minDecimals = 0, + truncate = false +): string { + let display = value; + if (truncate) { + const factor = 10 ** maxDecimals; + display = Math.trunc(display * factor) / factor; + } + return display.toLocaleString('id-ID', { + maximumFractionDigits: maxDecimals, + minimumFractionDigits: minDecimals, + }); +} + +export function formatRatio(value: number, decimals = 3): string { + const factor = 10 ** decimals; + const truncated = Math.trunc(value * factor) / factor; + return truncated.toFixed(decimals); +} + +export function formatDateId(iso: string | null | undefined): string { + if (!iso) return '—'; + const date = new Date(`${iso}T00:00:00`); + if (Number.isNaN(date.getTime())) return iso; + return date.toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' }); +} + +export function formatDateRange(startIso: string, endIso?: string | null): string { + if (!endIso) return formatDateId(startIso); + return `${formatDateId(startIso)} – ${formatDateId(endIso)}`; +} + +export function todayIso(): string { + const now = new Date(); + const pad = (n: number) => String(n).padStart(2, '0'); + return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`; +} + +export function addDaysIso(iso: string, days: number): string { + const date = new Date(`${iso}T00:00:00`); + date.setDate(date.getDate() + days); + const pad = (n: number) => String(n).padStart(2, '0'); + return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`; +} + +export function cycleDayForDate(startDate: string, isoDate: string): number { + const start = new Date(`${startDate}T00:00:00`); + const current = new Date(`${isoDate}T00:00:00`); + const diff = Math.round((current.getTime() - start.getTime()) / 86400000); + return Math.max(0, diff); +} + +export function inclusiveDayCount(startIso: string, endIso: string): number { + return Math.max(1, cycleDayForDate(startIso, endIso) + 1); +} + +export type CycleStatusUi = 'active' | 'pending_close' | 'closed'; + +export function resolveCycleStatus(cycle: { + status?: string; + end_date?: string | null; + visible_through_date?: string; +}): CycleStatusUi { + if (cycle.status === 'pending_close' || cycle.status === 'closed' || cycle.status === 'active') { + return cycle.status; + } + if (cycle.end_date && cycle.visible_through_date && cycle.visible_through_date >= cycle.end_date) { + return 'closed'; + } + return 'active'; +} diff --git a/utils/kandangRanking.ts b/utils/kandangRanking.ts new file mode 100644 index 0000000..5e547ea --- /dev/null +++ b/utils/kandangRanking.ts @@ -0,0 +1,168 @@ +import { api } from '../services/apiClient.ts'; +import type { Cycle, KPI, Site } from '../types/api.ts'; + +export type KandangRankingRow = { + rank: number; + siteId: number; + siteName: string; + kandangId: number; + kandangName: string; + cycleId: number; + startDate: string; + endDate: string; + totalDays: number; + eef: number | null; + fcr: number | null; +}; + +export type LoadKandangRankingArgs = { + sites: Site[]; + months: number; + /** Defaults to today (local). */ + now?: Date; +}; + +function toIsoDate(d: Date): string { + const pad = (n: number) => String(n).padStart(2, '0'); + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; +} + +/** Inclusive lower bound: end_date >= (today − months). */ +export function rankingWindowStart(months: number, now = new Date()): string { + const start = new Date(now.getFullYear(), now.getMonth(), now.getDate()); + start.setMonth(start.getMonth() - months); + return toIsoDate(start); +} + +export function isEndDateInWindow(endDate: string | null | undefined, windowStart: string): boolean { + if (!endDate) return false; + return endDate >= windowStart; +} + +/** + * Latest valid FCR/EEF for a cycle. + * Matches EefDashboardPage: sort by age/date ascending, then walk from the end. + * (API KPI list is ordered `-date` / newest-first — do not assume array order.) + */ +export function latestValidRatios(kpis: KPI[]): { eef: number | null; fcr: number | null } { + const sorted = [...kpis].sort((a, b) => a.age - b.age || a.date.localeCompare(b.date)); + let eef: number | null = null; + let fcr: number | null = null; + for (let i = sorted.length - 1; i >= 0; i--) { + const row = sorted[i]; + if (!row) continue; + if (eef == null && row.eef > 0) eef = row.eef; + if (fcr == null && row.fcr > 0) fcr = row.fcr; + if (eef != null && fcr != null) break; + } + return { eef, fcr }; +} + +function assignRanks( + rows: Omit[] +): KandangRankingRow[] { + const withEef = rows + .filter((r) => r.eef != null) + .sort((a, b) => (b.eef as number) - (a.eef as number)); + const withoutEef = rows.filter((r) => r.eef == null); + + const ranked: KandangRankingRow[] = withEef.map((row, index) => ({ + ...row, + rank: index + 1, + })); + const unranked: KandangRankingRow[] = withoutEef.map((row) => ({ + ...row, + rank: 0, + })); + return [...ranked, ...unranked]; +} + +/** + * Load closed-cycle EEF rankings for the given sites within a months window. + * Uses one closed-cycles list + per-site kandangs + per-cycle KPI fetches. + */ +export async function loadKandangRanking({ + sites, + months, + now = new Date(), +}: LoadKandangRankingArgs): Promise { + if (sites.length === 0 || months < 1) return []; + + const windowStart = rankingWindowStart(months, now); + const siteById = new Map(sites.map((s) => [s.id, s])); + + const kandangLists = await Promise.all( + sites.map((site) => api.kandangs.list({ site_id: site.id })) + ); + + type KandangMeta = { siteId: number; siteName: string; kandangName: string }; + const kandangMeta = new Map(); + kandangLists.forEach((list, i) => { + const site = sites[i]; + if (!site) return; + for (const k of list) { + kandangMeta.set(k.id, { + siteId: site.id, + siteName: site.site_name, + kandangName: k.kandang_name, + }); + } + }); + + if (kandangMeta.size === 0) return []; + + let closedCycles: Cycle[] = []; + try { + closedCycles = await api.cycles.list({ status: 'closed' }); + } catch { + // Fallback: per-kandang if global closed list fails + const perKandang = await Promise.all( + [...kandangMeta.keys()].map(async (kandangId) => { + try { + return await api.cycles.list({ kandang_id: kandangId, status: 'closed' }); + } catch { + return [] as Cycle[]; + } + }) + ); + closedCycles = perKandang.flat(); + } + + const inScope = closedCycles.filter((cycle) => { + if (!kandangMeta.has(cycle.kandang)) return false; + return isEndDateInWindow(cycle.end_date, windowStart); + }); + + const metricRows = await Promise.all( + inScope.map(async (cycle) => { + const meta = kandangMeta.get(cycle.kandang); + if (!meta || !cycle.end_date) return null; + // Ensure site still in requested set (defensive) + if (!siteById.has(meta.siteId)) return null; + + let eef: number | null = null; + let fcr: number | null = null; + try { + const kpis = await api.kpis.list({ cycle_id: cycle.id }); + ({ eef, fcr } = latestValidRatios(kpis)); + } catch { + // leave nulls + } + + return { + siteId: meta.siteId, + siteName: meta.siteName, + kandangId: cycle.kandang, + kandangName: meta.kandangName || cycle.kandang_name, + cycleId: cycle.id, + startDate: cycle.start_date, + endDate: cycle.end_date, + totalDays: cycle.total_days || cycle.current_day || 0, + eef, + fcr, + } satisfies Omit; + }) + ); + + return assignRanks(metricRows.filter((r): r is Omit => r != null)); +} diff --git a/utils/pdfExport.ts b/utils/pdfExport.ts new file mode 100644 index 0000000..3025802 --- /dev/null +++ b/utils/pdfExport.ts @@ -0,0 +1,131 @@ +import { jsPDF } from 'jspdf'; +import html2canvas from 'html2canvas'; + +const PAGE_WIDTH_MM = 210; +const PAGE_HEIGHT_MM = 297; +const MARGIN_MM = 10; +const CONTENT_WIDTH_MM = PAGE_WIDTH_MM - MARGIN_MM * 2; +const USABLE_HEIGHT_MM = PAGE_HEIGHT_MM - MARGIN_MM * 2; + +export const usableHeightCssPx = (widthPx: number): number => + (USABLE_HEIGHT_MM / CONTENT_WIDTH_MM) * widthPx; + +/** + * Safe page-break offsets for `data-pdf-block` nodes. + * + * A block's start is only a break point when the whole block fits on one page. + * Oversized tables (e.g. a 49-day report) must start under the header instead + * of being deferred to page 2. + */ +export function pdfBlockBreakOffsets( + blocks: Array<{ top: number; bottom: number }>, + usableHeightPx: number +): number[] { + const breaks: number[] = []; + for (const block of blocks) { + const height = block.bottom - block.top; + if (height <= usableHeightPx && block.top > 0) { + breaks.push(block.top); + } + if (block.bottom > 0) { + breaks.push(block.bottom); + } + } + return [...new Set(breaks.map((value) => Math.round(value)))].sort((a, b) => a - b); +} + +export function choosePdfSliceHeight( + cursor: number, + canvasHeight: number, + usableHeightPx: number, + breakPoints: number[] +): number { + const remaining = canvasHeight - cursor; + if (remaining <= usableHeightPx) return remaining; + const limit = cursor + usableHeightPx; + const candidate = [...breakPoints].reverse().find((point) => point > cursor && point <= limit); + return candidate ? candidate - cursor : usableHeightPx; +} + +/** + * Render an element to a multi-page A4 PDF. + * + * html2canvas photographs the whole report once, then the canvas is sliced at + * `data-pdf-block` boundaries (so a page break never cuts through a table) and + * each slice is written as a compressed JPEG page. + */ +export async function exportElementToPdf( + element: HTMLElement, + filename: string, + options?: { widthPx?: number } +): Promise { + const widthPx = options?.widthPx ?? 800; + const scale = 1.5; + const jpegQuality = 0.82; + const blockRects: Array<{ top: number; bottom: number }> = []; + + const canvas = await html2canvas(element, { + scale, + useCORS: true, + backgroundColor: '#ffffff', + windowWidth: widthPx, + onclone: (_clonedDoc, clonedElement) => { + clonedElement.style.width = `${widthPx}px`; + clonedElement.style.maxWidth = `${widthPx}px`; + clonedElement.style.margin = '0'; + + const top = clonedElement.getBoundingClientRect().top; + clonedElement.querySelectorAll('[data-pdf-block]').forEach((node) => { + const rect = node.getBoundingClientRect(); + blockRects.push({ top: rect.top - top, bottom: rect.bottom - top }); + }); + }, + }); + + const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4', compress: true }); + const pageWidthMm = doc.internal.pageSize.getWidth(); + const pageHeightMm = doc.internal.pageSize.getHeight(); + const contentWidthMm = pageWidthMm - MARGIN_MM * 2; + const usableHeightMm = pageHeightMm - MARGIN_MM * 2; + + const mmPerPx = contentWidthMm / canvas.width; + const usableHeightPx = usableHeightMm / mmPerPx; + const safeBreaks = pdfBlockBreakOffsets(blockRects, usableHeightCssPx(widthPx)); + + // Clone-CSS px -> canvas px, de-duplicated and ordered. + const breakPoints = [...new Set(safeBreaks.map((value) => Math.round(value * scale)))] + .filter((value) => value > 0 && value < canvas.height) + .sort((a, b) => a - b); + + let cursor = 0; + let firstPage = true; + + while (cursor < canvas.height) { + const sliceHeight = choosePdfSliceHeight(cursor, canvas.height, usableHeightPx, breakPoints); + if (sliceHeight <= 0) break; + + const slice = document.createElement('canvas'); + slice.width = canvas.width; + slice.height = Math.max(1, Math.round(sliceHeight)); + const ctx = slice.getContext('2d'); + if (!ctx) break; + ctx.fillStyle = '#ffffff'; + ctx.fillRect(0, 0, slice.width, slice.height); + ctx.drawImage(canvas, 0, cursor, canvas.width, slice.height, 0, 0, canvas.width, slice.height); + + if (!firstPage) doc.addPage(); + doc.addImage( + slice.toDataURL('image/jpeg', jpegQuality), + 'JPEG', + MARGIN_MM, + MARGIN_MM, + contentWidthMm, + slice.height * mmPerPx + ); + + firstPage = false; + cursor += slice.height; + } + + doc.save(filename); +} diff --git a/utils/reportExcel.ts b/utils/reportExcel.ts new file mode 100644 index 0000000..70bbc24 --- /dev/null +++ b/utils/reportExcel.ts @@ -0,0 +1,467 @@ +import ExcelJS from 'exceljs'; +import type { DashboardReportPayload } from '../types/dashboardReport.ts'; +import { + countingTotals, + feedInTotals, + feedOutTotals, + feedUseTotals, +} from './reportTotals.ts'; +import { formatDateId, formatDateRange, formatNumber, formatRatio } from './format.ts'; +import { buildReportSummary, formatSummaryValue } from './reportSummary.ts'; + +const COLORS = { + headerFill: 'FFF8FAFC', + headerFont: 'FF475569', + accentFill: 'FF6D28D0', + accentDeep: 'FF5B21B6', + accentFont: 'FFFFFFFF', + totalFill: 'FFF1F5F9', + zebraFill: 'FFFAFAFA', + border: 'FFE2E8F0', + titleFont: 'FF111827', + metaFont: 'FF374151', +}; + +const thinBorder: Partial = { + top: { style: 'thin', color: { argb: COLORS.border } }, + left: { style: 'thin', color: { argb: COLORS.border } }, + bottom: { style: 'thin', color: { argb: COLORS.border } }, + right: { style: 'thin', color: { argb: COLORS.border } }, +}; + +type CellValue = string | number | null; + +const isPresent = (value: number | null | undefined): value is number => + typeof value === 'number' && Number.isFinite(value); + +const dash = (value: number | null | undefined): CellValue => + isPresent(value) ? value : '-'; + +const na = (value: number | null | undefined): CellValue => + isPresent(value) ? value : 'N/A'; + +const pct = (value: number | null | undefined): CellValue => + isPresent(value) ? `${value.toFixed(1)}%` : 'N/A'; + +const qty = (value: number | null | undefined, maxDecimals = 0, suffix = ''): CellValue => { + if (!isPresent(value)) return 'N/A'; + return `${formatNumber(value, maxDecimals, 0, true)}${suffix}`; +}; + +const ratio = (value: number | null | undefined): string => + isPresent(value) ? formatRatio(value, 3) : 'N/A'; + +const harvestKg = (grams: number | null | undefined): CellValue => { + if (!isPresent(grams)) return 'N/A'; + return `${formatNumber(grams / 1000, 1)} kg`; +}; + +function styleHeaderRow(row: ExcelJS.Row, colCount: number): void { + row.height = 22; + for (let c = 1; c <= colCount; c += 1) { + const cell = row.getCell(c); + cell.font = { bold: true, color: { argb: COLORS.headerFont }, size: 11 }; + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: COLORS.headerFill } }; + cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true }; + cell.border = thinBorder; + } +} + +function styleDataRow(row: ExcelJS.Row, colCount: number, stripe: boolean): void { + for (let c = 1; c <= colCount; c += 1) { + const cell = row.getCell(c); + cell.font = { size: 11, color: { argb: COLORS.titleFont } }; + cell.alignment = { + vertical: 'middle', + horizontal: c === 1 ? 'left' : 'right', + }; + if (stripe) { + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: COLORS.zebraFill } }; + } + cell.border = thinBorder; + } +} + +function styleTotalRow(row: ExcelJS.Row, colCount: number): void { + row.height = 22; + for (let c = 1; c <= colCount; c += 1) { + const cell = row.getCell(c); + cell.font = { bold: true, size: 11, color: { argb: COLORS.titleFont } }; + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: COLORS.totalFill } }; + cell.alignment = { + vertical: 'middle', + horizontal: c === 1 ? 'left' : 'right', + }; + cell.border = { + ...thinBorder, + top: { style: 'medium', color: { argb: COLORS.border } }, + }; + } +} + +function styleHighlightKpiRow(row: ExcelJS.Row, colCount: number): void { + row.height = 28; + const highlightBorder: Partial = { + top: { style: 'medium', color: { argb: COLORS.accentDeep } }, + left: { style: 'medium', color: { argb: COLORS.accentDeep } }, + bottom: { style: 'medium', color: { argb: COLORS.accentDeep } }, + right: { style: 'medium', color: { argb: COLORS.accentDeep } }, + }; + for (let c = 1; c <= colCount; c += 1) { + const cell = row.getCell(c); + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: COLORS.accentFill } }; + cell.font = { + bold: true, + size: c === 2 ? 14 : 11, + color: { argb: COLORS.accentFont }, + }; + cell.alignment = { + vertical: 'middle', + horizontal: c === 2 ? 'center' : 'left', + }; + cell.border = highlightBorder; + } +} + +function autoFitColumns(sheet: ExcelJS.Worksheet, min = 10, max = 42): void { + sheet.columns.forEach((column) => { + let maxLen = min; + column.eachCell?.({ includeEmpty: false }, (cell) => { + const text = + cell.value instanceof Date + ? cell.value.toLocaleDateString('id-ID') + : String(cell.value ?? ''); + maxLen = Math.max(maxLen, text.length); + }); + column.width = Math.min(max, Math.max(min, maxLen + 2)); + }); +} + +function addSheetTitle(sheet: ExcelJS.Worksheet, title: string, colCount: number): void { + sheet.mergeCells(1, 1, 1, colCount); + const cell = sheet.getCell(1, 1); + cell.value = title; + cell.font = { bold: true, size: 13, color: { argb: COLORS.titleFont } }; + cell.alignment = { vertical: 'middle', horizontal: 'left' }; + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: COLORS.headerFill } }; + cell.border = { + ...thinBorder, + bottom: { style: 'medium', color: { argb: COLORS.accentFill } }, + }; + sheet.getRow(1).height = 26; +} + +function addTable( + sheet: ExcelJS.Worksheet, + title: string, + headers: string[], + rows: CellValue[][], + totalRow?: CellValue[] | null +): void { + const colCount = headers.length; + addSheetTitle(sheet, title, colCount); + + const headerRow = sheet.addRow(headers); + styleHeaderRow(headerRow, colCount); + + rows.forEach((values, index) => { + const row = sheet.addRow(values); + styleDataRow(row, colCount, index % 2 === 1); + }); + + if (totalRow) { + const row = sheet.addRow(totalRow); + styleTotalRow(row, colCount); + } + + sheet.views = [{ state: 'frozen', ySplit: 2, activeCell: 'A3' }]; + autoFitColumns(sheet); +} + +function addSummarySheet(workbook: ExcelJS.Workbook, payload: DashboardReportPayload): void { + const isEndCycle = payload.reportType === 'end_cycle'; + const title = isEndCycle ? 'Laporan Akhir Siklus' : 'Laporan Harian'; + const lastDate = payload.counting[payload.counting.length - 1]?.date ?? payload.cycleStart; + const printedDate = new Date(payload.generatedAt).toLocaleDateString('id-ID', { + day: 'numeric', + month: 'long', + year: 'numeric', + }); + + const sheet = workbook.addWorksheet('Ringkasan'); + sheet.getColumn(1).width = 22; + sheet.getColumn(2).width = 48; + + const addMeta = (label: string, value: string | number, bold = false): void => { + const row = sheet.addRow([label, value]); + row.getCell(1).font = { bold: true, size: 11, color: { argb: COLORS.metaFont } }; + row.getCell(2).font = { + bold, + size: bold ? 14 : 11, + color: { argb: COLORS.titleFont }, + }; + row.height = bold ? 24 : 20; + }; + + sheet.getCell('A1').value = 'Dashboard CPSP'; + sheet.getCell('A1').font = { bold: true, size: 10, color: { argb: COLORS.accentFill } }; + sheet.addRow([]); + + addMeta('Judul', title, true); + addMeta('Lokasi', `${payload.area} — ${payload.kandangName}`); + addMeta( + 'Periode', + `Hari ke-0 s/d ke-${payload.upToDay} (${formatDateId(payload.cycleStart)} - ${formatDateId(lastDate)})` + ); + addMeta('Siklus', formatDateRange(payload.cycleStart, payload.cycleEnd)); + addMeta( + 'Berat DOC', + payload.docWeight == null || !Number.isFinite(payload.docWeight) + ? '—' + : `${formatNumber(payload.docWeight, 1, 0, true)} gram` + ); + addMeta('Dicetak', printedDate); + + sheet.addRow([]); + const kpiTitle = sheet.addRow(['Ringkasan KPI']); + kpiTitle.getCell(1).font = { + bold: true, + size: 12, + color: { argb: COLORS.accentFill }, + }; + + sheet.getColumn(3).width = 12; + const kpiHeader = sheet.addRow(['Metrik', 'Nilai', 'Satuan']); + styleHeaderRow(kpiHeader, 3); + + const summary = buildReportSummary(payload); + let insertedHighlightGap = false; + summary.metrics.forEach((metric, index) => { + const isHighlight = metric.key === 'fcr' || metric.key === 'eef'; + if (isHighlight && !insertedHighlightGap) { + sheet.addRow([]); + insertedHighlightGap = true; + } + const row = sheet.addRow([ + metric.label, + formatSummaryValue(metric), + metric.unit || '—', + ]); + if (isHighlight) { + styleHighlightKpiRow(row, 3); + } else { + styleDataRow(row, 3, index % 2 === 1); + row.getCell(1).alignment = { vertical: 'middle', horizontal: 'left' }; + row.getCell(2).alignment = { vertical: 'middle', horizontal: 'right' }; + row.getCell(3).alignment = { vertical: 'middle', horizontal: 'left' }; + } + }); + + sheet.addRow([]); + const navHeader = sheet.addRow(['Sheet', 'Isi']); + styleHeaderRow(navHeader, 2); + + const navRows: Array<[string, string]> = [ + ['Hitung Ayam', 'Stok, mortalitas, panen, dan akurasi hitung harian'], + ['Berat Ayam', 'Rata-rata berat manual vs IoT dan akurasi'], + ['Karung Masuk', 'Pakan masuk manual vs IoT'], + ['Karung Dituang', 'Pakan dituang manual vs IoT'], + ['Karung Keluar', 'Pakan keluar manual vs IoT'], + ]; + if (isEndCycle) { + navRows.push(['FCR', 'Data pendukung FCR per umur']); + navRows.push(['EEF', 'Data pendukung EEF per umur']); + } + + navRows.forEach(([name, desc], index) => { + const row = sheet.addRow([name, desc]); + styleDataRow(row, 2, index % 2 === 1); + }); +} + +export async function downloadReportExcel(payload: DashboardReportPayload): Promise { + const workbook = new ExcelJS.Workbook(); + workbook.creator = 'Dashboard CPSP'; + workbook.created = new Date(); + + addSummarySheet(workbook, payload); + + const countingTotal = countingTotals(payload.counting); + addTable( + workbook.addWorksheet('Hitung Ayam'), + 'Hitung Ayam harian', + [ + 'Tanggal', + 'Umur (hari)', + 'Stok awal', + 'Mortalitas', + 'Panen', + 'Berat panen', + 'Stok akhir', + 'IoT', + 'Akurasi %', + ], + payload.counting.map((row) => [ + formatDateId(row.date), + row.day, + na(row.countBefore), + na(row.mortality), + na(row.harvest), + na(row.harvestWeight), + na(row.countAfter), + na(row.iotCount), + pct(row.accuracy), + ]), + countingTotal + ? [ + countingTotal.label, + '—', + dash(countingTotal.countBefore), + na(countingTotal.mortality), + na(countingTotal.harvest), + na(countingTotal.harvestWeight), + dash(countingTotal.countAfter), + dash(countingTotal.iotCount), + countingTotal.accuracy == null ? '-' : pct(countingTotal.accuracy), + ] + : null + ); + + addTable( + workbook.addWorksheet('Berat Ayam'), + 'Berat Ayam harian', + [ + 'Tanggal', + 'Umur (hari)', + 'Rata-rata manual', + 'Rata-rata IoT', + 'Keseragaman', + 'Selisih', + 'Akurasi %', + ], + payload.weight.map((row) => [ + formatDateId(row.date), + row.day, + na(row.avgManual), + na(row.avgIot), + pct(row.uniformity), + na(row.difference), + pct(row.accuracy), + ]) + ); + + const feedInTotal = feedInTotals(payload.feedIn); + addTable( + workbook.addWorksheet('Karung Masuk'), + 'Karung masuk', + ['Tanggal', 'Manual masuk', 'IoT masuk', 'Akurasi %'], + payload.feedIn.map((row) => [ + formatDateId(row.date), + na(row.manualIn), + na(row.iotIn), + pct(row.accuracy), + ]), + feedInTotal + ? [ + feedInTotal.label, + na(feedInTotal.manualIn), + na(feedInTotal.iotIn), + pct(feedInTotal.accuracy), + ] + : null + ); + + const feedUseTotal = feedUseTotals(payload.feedUse); + addTable( + workbook.addWorksheet('Karung Dituang'), + 'Karung dituang', + ['Tanggal', 'Umur (hari)', 'Manual dituang', 'IoT dituang', 'Akurasi %'], + payload.feedUse.map((row) => [ + formatDateId(row.date), + row.day, + na(row.manualUse), + na(row.iotUse), + pct(row.accuracy), + ]), + feedUseTotal + ? [ + feedUseTotal.label, + '—', + na(feedUseTotal.manualUse), + na(feedUseTotal.iotUse), + pct(feedUseTotal.accuracy), + ] + : null + ); + + const feedOutTotal = feedOutTotals(payload.feedOut); + addTable( + workbook.addWorksheet('Karung Keluar'), + 'Karung keluar', + ['Tanggal', 'Manual keluar', 'IoT keluar', 'Akurasi %'], + payload.feedOut.map((row) => [ + formatDateId(row.date), + na(row.manualOut), + na(row.iotOut), + pct(row.accuracy), + ]), + feedOutTotal + ? [ + feedOutTotal.label, + na(feedOutTotal.manualOut), + na(feedOutTotal.iotOut), + pct(feedOutTotal.accuracy), + ] + : null + ); + + if (payload.reportType === 'end_cycle') { + addTable( + workbook.addWorksheet('FCR'), + 'Data Pendukung FCR', + ['Umur', 'Total Pakan', 'Bobot IoT', 'Ayam Hidup', 'Total Bobot Panen', 'FCR'], + payload.fcr.map((row) => [ + `Hari ${row.day}`, + qty(row.feedTotal, 0, ' karung'), + qty(row.iotWeight, 2, row.iotWeight != null ? ' g' : ''), + qty(row.chickenLife, 0, ' ekor'), + harvestKg(row.harvestWeightTotal), + ratio(row.iotFcr), + ]) + ); + + addTable( + workbook.addWorksheet('EEF'), + 'Data Pendukung EEF', + [ + 'Umur', + 'Persentase Ayam Hidup', + 'BW Rata-rata Panen', + 'Umur Rata-rata Panen', + 'FCR', + 'EEF', + ], + payload.eef.map((row) => [ + `Hari ${row.day}`, + qty(row.chickenLifePercentage, 3, '%'), + qty(row.iotAverageHarvestBw, 2, row.iotAverageHarvestBw != null ? ' g' : ''), + qty(row.iotAverageDayWeight, 2), + ratio(row.iotFcr), + ratio(row.iotEef), + ]) + ); + } + + const buffer = await workbook.xlsx.writeBuffer(); + const blob = new Blob([buffer], { + type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + }); + const period = + payload.reportType === 'end_cycle' ? 'Akhir-Siklus' : `Harian-Hari-${payload.upToDay}`; + const url = URL.createObjectURL(blob); + const anchor = document.createElement('a'); + anchor.href = url; + anchor.download = `Laporan-${period}-${payload.area}-${payload.kandangName}-${payload.cycleStart}_sd_${payload.cycleEnd}.xlsx`; + anchor.click(); + URL.revokeObjectURL(url); +} diff --git a/utils/reportSummary.ts b/utils/reportSummary.ts new file mode 100644 index 0000000..7f72201 --- /dev/null +++ b/utils/reportSummary.ts @@ -0,0 +1,166 @@ +import type { DashboardReportPayload } from '../types/dashboardReport.ts'; +import { + countingTotals, + feedInTotals, + feedOutTotals, + feedUseTotals, +} from './reportTotals.ts'; +import { formatNumber, formatRatio } from './format.ts'; + +export type ReportSummaryMetricKey = + | 'umur' + | 'docWeight' + | 'populasi' + | 'mortalitas' + | 'panen' + | 'beratPanen' + | 'karungMasuk' + | 'karungDituang' + | 'beratPakan' + | 'karungKeluar' + | 'beratAvg' + | 'uniformity' + | 'fcr' + | 'eef'; + +export interface ReportSummaryMetric { + key: ReportSummaryMetricKey; + label: string; + value: number | null; + unit: string; +} + +export interface ReportSummary { + metrics: ReportSummaryMetric[]; +} + +const isPresent = (value: number | null | undefined): value is number => + typeof value === 'number' && Number.isFinite(value); + +/** kg per karung — same factor as Dashboard feed weight panel */ +const FEED_SACK_KG = 50; + +export function latestValidRatio( + rows: Array<{ iotFcr?: number | null; iotEef?: number | null }>, + key: 'iotFcr' | 'iotEef' +): number | null { + for (let i = rows.length - 1; i >= 0; i -= 1) { + const value = rows[i]?.[key]; + if (typeof value === 'number' && Number.isFinite(value)) return value; + } + return null; +} + +export function buildReportSummary(payload: DashboardReportPayload): ReportSummary { + const lastCounting = payload.counting[payload.counting.length - 1] ?? null; + const lastWeight = payload.weight[payload.weight.length - 1] ?? null; + const counting = countingTotals(payload.counting); + const feedIn = feedInTotals(payload.feedIn); + const feedUse = feedUseTotals(payload.feedUse); + const feedOut = feedOutTotals(payload.feedOut); + + const beratAvg = lastWeight + ? isPresent(lastWeight.avgIot) + ? lastWeight.avgIot + : isPresent(lastWeight.avgManual) + ? lastWeight.avgManual + : null + : null; + + const metrics: ReportSummaryMetric[] = [ + { key: 'umur', label: 'Umur', value: payload.upToDay, unit: 'hari' }, + { + key: 'docWeight', + label: 'Berat DOC', + value: isPresent(payload.docWeight) ? payload.docWeight : null, + unit: 'gram', + }, + { + key: 'populasi', + label: 'Populasi', + value: isPresent(lastCounting?.countAfter) ? lastCounting!.countAfter : null, + unit: 'ekor', + }, + { + key: 'mortalitas', + label: 'Mortalitas', + value: counting?.mortality ?? null, + unit: 'ekor', + }, + { + key: 'panen', + label: 'Panen', + value: counting?.harvest ?? null, + unit: 'ekor', + }, + { + key: 'beratPanen', + label: 'Berat Panen', + // counting harvestWeight is stored in grams; surface kg for the summary card + value: isPresent(counting?.harvestWeight) ? counting!.harvestWeight / 1000 : null, + unit: 'kg', + }, + { + key: 'karungMasuk', + label: 'Karung Masuk', + value: feedIn?.manualIn ?? null, + unit: 'karung', + }, + { + key: 'karungDituang', + label: 'Karung Dituang', + value: feedUse?.manualUse ?? null, + unit: 'karung', + }, + { + key: 'beratPakan', + label: 'Berat Pakan', + value: isPresent(feedUse?.manualUse) ? feedUse!.manualUse * FEED_SACK_KG : null, + unit: 'kg', + }, + { + key: 'karungKeluar', + label: 'Karung Keluar', + value: feedOut?.manualOut ?? null, + unit: 'karung', + }, + { key: 'beratAvg', label: 'Berat AVG', value: beratAvg, unit: 'gram' }, + { + key: 'uniformity', + label: 'Uniformity', + value: isPresent(lastWeight?.uniformity) ? lastWeight!.uniformity : null, + unit: '%', + }, + { + key: 'fcr', + label: 'FCR', + value: latestValidRatio(payload.fcr, 'iotFcr'), + unit: '', + }, + { + key: 'eef', + label: 'EEF', + value: latestValidRatio(payload.eef, 'iotEef'), + unit: '', + }, + ]; + + return { metrics }; +} + +export function formatSummaryValue(metric: ReportSummaryMetric): string { + if (!isPresent(metric.value)) return '—'; + if (metric.key === 'fcr' || metric.key === 'eef') { + return formatRatio(metric.value, 3); + } + if ( + metric.key === 'uniformity' || + metric.key === 'beratAvg' || + metric.key === 'beratPanen' || + metric.key === 'beratPakan' || + metric.key === 'docWeight' + ) { + return formatNumber(metric.value, 1, 0, true); + } + return formatNumber(metric.value, 0, 0, true); +} diff --git a/utils/reportTotals.ts b/utils/reportTotals.ts new file mode 100644 index 0000000..0c209d5 --- /dev/null +++ b/utils/reportTotals.ts @@ -0,0 +1,112 @@ +import type { + DashboardReportCountingRow, + DashboardReportFeedInRow, + DashboardReportFeedOutRow, + DashboardReportFeedUseRow, +} from '../types/dashboardReport.ts'; + +export const REPORT_TOTAL_LABEL = 'Total'; + +const isPresentNumber = (value: number | null | undefined): value is number => + typeof value === 'number' && Number.isFinite(value); + +function sumPresent(values: Array): number | null { + let total = 0; + let any = false; + for (const value of values) { + if (!isPresentNumber(value)) continue; + total += value; + any = true; + } + return any ? total : null; +} + +const sackAccuracy = (manual: number | null, iot: number | null): number | null => { + if (manual != null && iot != null && manual > 0 && iot > 0) { + return Math.round((Math.min(manual, iot) / Math.max(manual, iot)) * 1000) / 10; + } + if (manual === 0 && iot === 0) return 100; + return null; +}; + +export interface CountingTotalsRow { + label: string; + countBefore: number | null; + mortality: number | null; + harvest: number | null; + harvestWeight: number | null; + countAfter: number | null; + iotCount: number | null; + accuracy: number | null; +} + +export interface FeedInTotalsRow { + label: string; + manualIn: number | null; + iotIn: number | null; + accuracy: number | null; +} + +export interface FeedUseTotalsRow { + label: string; + manualUse: number | null; + iotUse: number | null; + accuracy: number | null; +} + +export interface FeedOutTotalsRow { + label: string; + manualOut: number | null; + iotOut: number | null; + accuracy: number | null; +} + +export function countingTotals(rows: DashboardReportCountingRow[]): CountingTotalsRow | null { + if (!rows.length) return null; + return { + label: REPORT_TOTAL_LABEL, + countBefore: null, + mortality: sumPresent(rows.map((row) => row.mortality)), + harvest: sumPresent(rows.map((row) => row.harvest)), + harvestWeight: sumPresent(rows.map((row) => row.harvestWeight)), + countAfter: null, + iotCount: null, + accuracy: null, + }; +} + +export function feedInTotals(rows: DashboardReportFeedInRow[]): FeedInTotalsRow | null { + if (!rows.length) return null; + const manualIn = sumPresent(rows.map((row) => row.manualIn)); + const iotIn = sumPresent(rows.map((row) => row.iotIn)); + return { + label: REPORT_TOTAL_LABEL, + manualIn, + iotIn, + accuracy: sackAccuracy(manualIn, iotIn), + }; +} + +export function feedUseTotals(rows: DashboardReportFeedUseRow[]): FeedUseTotalsRow | null { + if (!rows.length) return null; + const manualUse = sumPresent(rows.map((row) => row.manualUse)); + const iotUse = sumPresent(rows.map((row) => row.iotUse)); + return { + label: REPORT_TOTAL_LABEL, + manualUse, + iotUse, + accuracy: sackAccuracy(manualUse, iotUse), + }; +} + +export function feedOutTotals(rows: DashboardReportFeedOutRow[]): FeedOutTotalsRow | null { + if (!rows.length) return null; + const manualOut = sumPresent(rows.map((row) => row.manualOut)); + const iotOut = sumPresent(rows.map((row) => row.iotOut)); + return { + label: REPORT_TOTAL_LABEL, + manualOut, + iotOut, + accuracy: sackAccuracy(manualOut, iotOut), + }; +} diff --git a/utils/visibility.ts b/utils/visibility.ts new file mode 100644 index 0000000..285f1b7 --- /dev/null +++ b/utils/visibility.ts @@ -0,0 +1,18 @@ +/** Keep rows on or before the dashboard publish cutoff date (ISO `YYYY-MM-DD`). */ +export function throughVisibleDate( + rows: T[], + visibleThrough: string | null | undefined +): T[] { + if (!visibleThrough) return rows; + return rows.filter((row) => row.date <= visibleThrough); +} + +/** True when `date` is on or before the publish cutoff (or cutoff is unknown). */ +export function isOnOrBeforeVisibleDate( + date: string | null | undefined, + visibleThrough: string | null | undefined +): boolean { + if (!date) return false; + if (!visibleThrough) return true; + return date <= visibleThrough; +} diff --git a/utils/weight.ts b/utils/weight.ts new file mode 100644 index 0000000..c1f7365 --- /dev/null +++ b/utils/weight.ts @@ -0,0 +1,107 @@ +import { weightStandardData } from '../mockData/weightStandardData.ts'; + +/** + * Formats a weight value in grams into a locale-aware string. Values at or + * below 999 g stay in grams; larger values are shown in kg. Negative values + * (e.g. ADG during close-out) are shown with a minus sign. + * + * By default every value is shown with 4 decimal places (never rounded). + * Callers may override with options: + * - `decimals` decimal places to show (default 4) + * - `stripTrailingZeros` drop trailing zeros so the exact value is shown + * - `truncate` truncate instead of round (default false) + */ +export function formatWeight( + grams: number | null | undefined, + options?: { suffix?: string; decimals?: number; stripTrailingZeros?: boolean; truncate?: boolean } +): string { + const suffix = options?.suffix ?? ''; + const decimals = options?.decimals ?? 4; + const minDecimals = options?.stripTrailingZeros ? 0 : decimals; + + const format = (value: number, unit: string): string => { + let display = value; + if (options?.truncate) { + const factor = 10 ** decimals; + display = Math.trunc(display * factor) / factor; + } + const formatted = display.toLocaleString('id-ID', { + minimumFractionDigits: minDecimals, + maximumFractionDigits: decimals, + }); + return `${formatted} ${unit}${suffix}`; + }; + + if (grams == null) return format(0, 'g'); + const sign = grams < 0 ? '-' : ''; + const abs = Math.abs(grams); + const unit = abs <= 999 ? 'g' : 'kg'; + const display = abs <= 999 ? abs : abs / 1000; + return `${sign}${format(display, unit)}`; +} + +/** + * Picks the Ross 308 standard row for a DOC (chick-in) weight. + * Table rows are keyed by DOC weight (g) 35..51; columns are age days 1..35. + * Weights outside that range use the closest available row (e.g. 20→35, 60→51). + */ +function pickStandardValues(docWeight: number): number[] { + const rows = weightStandardData.data; + if (rows.length === 0) return []; + const exact = rows.find((row) => row.day === docWeight); + if (exact) return exact.values; + let closest = rows[0]!; + for (const row of rows) { + if (Math.abs(row.day - docWeight) < Math.abs(closest.day - docWeight)) { + closest = row; + } + } + return closest.values; +} + +/** Target body weight (grams) for a given age from the Ross 308 DOC-weight table. */ +export function getTargetWeightForAge(age: number, docWeight: number): number | null { + const values = pickStandardValues(docWeight); + if (age < 1 || age > values.length) return null; + return values[age - 1] ?? null; +} + +/** Target daily weight gain (grams/day) for a given age from the standard. */ +export function getTargetGainForAge(age: number, docWeight: number): number | null { + const values = pickStandardValues(docWeight); + if (age < 2 || age > values.length) return null; + const current = values[age - 1]; + const previous = values[age - 2]; + if (current == null || previous == null) return null; + return current - previous; +} + +export type WeightStatus = 'ok' | 'warning' | 'critical'; + +/** ADG threshold used by the old dashboard: >=60 ok, >=40 warning, else critical. */ +export function adgStatus(adg: number | null | undefined): WeightStatus { + if (adg == null || adg < 0) return 'critical'; + if (adg >= 60) return 'ok'; + if (adg >= 40) return 'warning'; + return 'critical'; +} + +/** Uniformity threshold (CP 707): >=80 ok, >=70 warning, else critical. */ +export function uniformityStatus(uniformity: number | null | undefined): WeightStatus { + if (uniformity == null || uniformity < 0) return 'critical'; + if (uniformity >= 80) return 'ok'; + if (uniformity >= 70) return 'warning'; + return 'critical'; +} + +/** Average-weight status from the deviation against the standard target. */ +export function weightDeviationStatus( + actual: number | null | undefined, + target: number | null | undefined +): WeightStatus { + if (actual == null || target == null || target <= 0) return 'ok'; + const deviation = ((actual - target) / target) * 100; + if (deviation < -20) return 'critical'; + if (deviation < -10) return 'warning'; + return 'ok'; +} diff --git a/vite-env.d.ts b/vite-env.d.ts new file mode 100644 index 0000000..7a7f1cd --- /dev/null +++ b/vite-env.d.ts @@ -0,0 +1,9 @@ +/// + +interface ImportMetaEnv { + readonly VITE_API_BASE?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..22c01dc --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,30 @@ +/// +import path from 'path'; +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, '.'), + }, + }, + server: { + // Avoid clash with site dashboard-cpsp (:3001 → :8000) + port: 3002, + host: '0.0.0.0', + proxy: { + '/api': { + target: 'http://127.0.0.1:8001', + changeOrigin: true, + }, + }, + }, + test: { + globals: true, + environment: 'jsdom', + setupFiles: './tests/setup.ts', + exclude: ['node_modules/**', 'dist/**'], + }, +});