ocearo-ui 0.1.22 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/404.html +1 -1
- package/README.fr.md +141 -157
- package/README.md +137 -157
- package/__next.__PAGE__.txt +19 -5
- package/__next._full.txt +12 -12
- package/__next._tree.txt +2 -2
- package/_next/static/chunks/0-c2-u5p6bxzo.js +1 -0
- package/_next/static/chunks/0h2qsuyze9ds1.js +1 -0
- package/_next/static/chunks/0iqdztntvxh3c.js +119 -0
- package/_next/static/chunks/0iztd835j5p1n.js +700 -0
- package/_next/static/chunks/{2nxsyowmuwpjy.js → 0jfox92up1jvy.js} +1 -1
- package/_next/static/chunks/0jpa5m78l0ib0.js +1 -0
- package/_next/static/chunks/0kpstejrka-7k.js +1 -0
- package/_next/static/chunks/0m7wbuocx-b4_.js +9 -0
- package/_next/static/chunks/0n95joti2n2py.js +3 -0
- package/_next/static/chunks/0ohleay4roayh.js +353 -0
- package/_next/static/chunks/0on1skx9l54-9.js +1 -0
- package/_next/static/chunks/0voiofm58khqd.js +1 -0
- package/_next/static/chunks/0w_skktmh3e48.js +1 -0
- package/_next/static/chunks/0y-dctk-kmqss.js +1 -0
- package/_next/static/chunks/0zwc9m4qgtwle.js +1 -0
- package/_next/static/chunks/11awvgcou7v4r.js +1 -0
- package/_next/static/chunks/144mjqdrx42lq.js +1 -0
- package/_next/static/chunks/15imr2-f_8n-x.js +1 -0
- package/_next/static/chunks/18_i6mf6hb_c7.js +1 -0
- package/_next/static/chunks/1d81m3g9jqkob.js +1 -0
- package/_next/static/chunks/1ed7ayfg19cjb.js +1 -0
- package/_next/static/chunks/1epya-yh2wvj2.js +1 -0
- package/_next/static/chunks/1exvcc71cgr4t.js +446 -0
- package/_next/static/chunks/1g8fbzv0hu0i2.js +1 -0
- package/_next/static/chunks/1gq4t2dyr7rq3.js +1 -0
- package/_next/static/chunks/1gt2hhqk1821k.js +9 -0
- package/_next/static/chunks/1l-jew0-1-3eq.js +30 -0
- package/_next/static/chunks/1pa1cfmfts0i9.js +1 -0
- package/_next/static/chunks/1ptj3mv8b_tzs.js +1 -0
- package/_next/static/chunks/1w1xks0hp_tlr.js +346 -0
- package/_next/static/chunks/1xekc18cyi4sx.js +1 -0
- package/_next/static/chunks/1y35unwvy8p98.js +1 -0
- package/_next/static/chunks/1zm03hw2ylxw8.js +1 -0
- package/_next/static/chunks/2aq8orcir5h03.js +1 -0
- package/_next/static/chunks/2dvwb-mfasp68.js +1 -0
- package/_next/static/chunks/2fdpvhx4oo81h.js +1 -0
- package/_next/static/chunks/2g-xpe7xnropn.js +409 -0
- package/_next/static/chunks/2kmptoy43h0mx.js +1 -0
- package/_next/static/chunks/2kwn4iymxaom3.js +1 -0
- package/_next/static/chunks/2n86yq1wz1yx7.js +1 -0
- package/_next/static/chunks/2rebcvig176xk.js +564 -0
- package/_next/static/chunks/2ryo_bbmt6t74.css +3 -0
- package/_next/static/chunks/2s6w3x5jnc2tg.js +1 -0
- package/_next/static/chunks/2w44atvyp9o_w.js +1 -0
- package/_next/static/chunks/2w71oj1brox5z.js +1 -0
- package/_next/static/chunks/2wayx8t5r5fi9.js +1 -0
- package/_next/static/chunks/3--qzv1u6c7_7.js +1 -0
- package/_next/static/chunks/32yn_fc-es66m.js +22 -0
- package/_next/static/chunks/34wvn5zw0a69w.js +1 -0
- package/_next/static/chunks/37t6vg8fb1-z8.js +1 -0
- package/_next/static/chunks/3nm7o0eq5abhg.js +1 -0
- package/_next/static/chunks/3p9ziqn6r35qf.js +1 -0
- package/_next/static/chunks/3q8o52_juxmdp.js +1 -0
- package/_next/static/chunks/3s6nzrbk-8mnv.js +31 -0
- package/_next/static/chunks/3td9mnhvcj9cq.js +1 -0
- package/_next/static/chunks/3wwn1rti8oc_r.js +1 -0
- package/_next/static/chunks/3zqx8h9yg5-ch.js +1 -0
- package/_next/static/chunks/turbopack-1h111qg8l92rw.js +1 -0
- package/_not-found/__next._full.txt +13 -13
- package/_not-found/__next._not-found.__PAGE__.txt +19 -2
- package/_not-found/__next._tree.txt +2 -2
- package/_not-found.html +1 -1
- package/_not-found.txt +13 -13
- package/apple-touch-icon.png +0 -0
- package/boats/boats.json +40 -5
- package/favicon-96x96.png +0 -0
- package/favicon.ico +0 -0
- package/favicon.svg +1 -3
- package/icons/favicon-16x16.png +0 -0
- package/icons/favicon-32x32.png +0 -0
- package/icons/favicon-48x48.png +0 -0
- package/icons/icon-192x192.png +0 -0
- package/icons/icon-512x512.png +0 -0
- package/icons/ocearo.webp +0 -0
- package/index.html +1 -1
- package/index.txt +12 -12
- package/manifest.json +2 -3
- package/package.json +15 -14
- package/settings/__next._full.txt +15 -15
- package/settings/__next._tree.txt +2 -2
- package/settings/__next.settings.__PAGE__.txt +22 -5
- package/settings.html +1 -1
- package/settings.txt +15 -15
- package/__next._head.txt +0 -6
- package/__next._index.txt +0 -5
- package/_next/static/chunks/0-z15txb4-uhu.js +0 -409
- package/_next/static/chunks/009rlietvsaq2.js +0 -1
- package/_next/static/chunks/070stlm97b9a2.js +0 -1
- package/_next/static/chunks/0abo2oxxw3hpi.js +0 -1
- package/_next/static/chunks/0jzbiie0nzar2.js +0 -1
- package/_next/static/chunks/0kinaai2rvd43.js +0 -9
- package/_next/static/chunks/0l9s4rhr00adq.js +0 -1
- package/_next/static/chunks/0qj7yy4f6sk8y.js +0 -455
- package/_next/static/chunks/0ri_um14-5x7u.js +0 -1
- package/_next/static/chunks/0uvr7xkt_5uno.js +0 -1
- package/_next/static/chunks/0yf1ifg_o1bq6.js +0 -1
- package/_next/static/chunks/0zbzk2ob0li1n.js +0 -1
- package/_next/static/chunks/0zjxnzbxh76mt.js +0 -1
- package/_next/static/chunks/17ma1x64d-211.js +0 -1
- package/_next/static/chunks/19xb2y6sgfnza.js +0 -1
- package/_next/static/chunks/1bz0tcmhjmjgh.js +0 -1
- package/_next/static/chunks/1d4h-sglyo8ft.js +0 -1
- package/_next/static/chunks/1gizigk3w6q7j.js +0 -31
- package/_next/static/chunks/1ptwltjb3h6jf.js +0 -4
- package/_next/static/chunks/1q572rz5m8mb-.js +0 -1
- package/_next/static/chunks/1rkf8qtk5-48h.js +0 -1
- package/_next/static/chunks/1sq_733weprvs.js +0 -1
- package/_next/static/chunks/26e1o1as-77nq.js +0 -172
- package/_next/static/chunks/27hn45pv56pv7.js +0 -393
- package/_next/static/chunks/28y-j215vt42m.js +0 -1
- package/_next/static/chunks/2a0yjir_3mk1m.js +0 -1
- package/_next/static/chunks/2atijj_pkc4uc.js +0 -2
- package/_next/static/chunks/2ccpehidlaq88.js +0 -1
- package/_next/static/chunks/2fy4q1c5l3tpj.js +0 -1
- package/_next/static/chunks/2lvvt2f1l5sfu.js +0 -1
- package/_next/static/chunks/2lw7kypuhij1_.css +0 -3
- package/_next/static/chunks/2nd5amcst4lhp.js +0 -1
- package/_next/static/chunks/2pwmb4pkqygy_.js +0 -1
- package/_next/static/chunks/2q_83f24jeg0e.js +0 -1
- package/_next/static/chunks/2rsdqsatgq9ta.js +0 -1
- package/_next/static/chunks/2udirievybq_j.js +0 -1
- package/_next/static/chunks/2urimbxg5bqv3.js +0 -1
- package/_next/static/chunks/32cbrrsp-x35l.js +0 -1
- package/_next/static/chunks/36ra6xjie0dsv.js +0 -9
- package/_next/static/chunks/3iuz3f0429awx.js +0 -1
- package/_next/static/chunks/3jh1u-s3k0bkk.js +0 -1
- package/_next/static/chunks/3jupxlga7r_do.js +0 -1
- package/_next/static/chunks/3m57lnggu30tr.js +0 -243
- package/_next/static/chunks/3myql5zu0rstt.js +0 -425
- package/_next/static/chunks/3rhgquok36e79.js +0 -1
- package/_next/static/chunks/42dfiu6iby3fq.js +0 -1
- package/_next/static/chunks/43ps2cu5ahf8n.js +0 -3
- package/_next/static/chunks/turbopack-0pirmko-w-775.js +0 -1
- package/_not-found/__next._head.txt +0 -6
- package/_not-found/__next._index.txt +0 -5
- package/_not-found/__next._not-found.txt +0 -5
- package/boats/ais/ais-30.glb +0 -0
- package/boats/ais/ais-31.glb +0 -0
- package/boats/ais/ais-35.glb +0 -0
- package/boats/ais/ais-36.glb +0 -0
- package/boats/ais/ais-37.glb +0 -0
- package/boats/ais/ais-40.glb +0 -0
- package/boats/ais/ais-50.glb +0 -0
- package/boats/ais/ais-60.glb +0 -0
- package/boats/ais/ais-70.glb +0 -0
- package/boats/ais/ais-80.glb +0 -0
- package/settings/__next._head.txt +0 -6
- package/settings/__next._index.txt +0 -5
- package/settings/__next.settings.txt +0 -5
- /package/_next/static/{sct9rcMTcCyBLHTxQQ75- → 01VWnAYjs9QwBnnMyWbQF}/_buildManifest.js +0 -0
- /package/_next/static/{sct9rcMTcCyBLHTxQQ75- → 01VWnAYjs9QwBnnMyWbQF}/_clientMiddlewareManifest.js +0 -0
- /package/_next/static/{sct9rcMTcCyBLHTxQQ75- → 01VWnAYjs9QwBnnMyWbQF}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -1,232 +1,212 @@
|
|
|
1
|
+
[](LICENSE)
|
|
2
|
+
[](https://www.npmjs.com/package/ocearo-ui)
|
|
3
|
+
[](https://signalk.org)
|
|
1
4
|
[](https://github.com/laborima/ocearo-ui/issues)
|
|
2
|
-
[](CONTRIBUTING.md)
|
|
3
|
-
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
5
|
|
|
5
6
|
[Français 🇫🇷](README.fr.md)
|
|
6
7
|
|
|
8
|
+
<p align="center">
|
|
9
|
+
<picture>
|
|
10
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/logo/ocearo-logo-dark.svg">
|
|
11
|
+
<img src="docs/logo/ocearo-logo-light.svg" alt="Ocearo" width="360">
|
|
12
|
+
</picture>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
7
15
|
# Ocearo UI
|
|
8
16
|
|
|
9
|
-
**
|
|
17
|
+
**The open-source sailing display for Signal K.** A clear, real-time 3D picture of the boat, the sea and the traffic around it — sail trim, rules of the road, man overboard, anchor watch, bathymetry and weather — in a calm interface inspired by Tesla's driving visualisation. It runs as a Signal K webapp on the boat's server (a Raspberry Pi is enough) and in any browser on board: chart-table screen, cockpit tablet or phone.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+

|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
> Every image on this page is a screenshot of the app, fed with real data for La Rochelle on 4 October 2026: wind from Open-Meteo, tides, the SHOM 20 m bathymetry and scripted AIS traffic.
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
▶ **Video tour (2:33):** [in English](https://youtu.be/YGQM3UipcvU) · [en français](https://youtu.be/GkLjk23Sz8k) — leaving La Rochelle, the rules of the road, man overboard, bathymetry, weather, engine and logbook.
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
---
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
- **KIP-style Card Compass**: The dashboard navigation tab now carries a rotating-rose compass with a fixed lubber line, COG and apparent-wind index markers, drawn in SVG. It replaces the 3D boat widget, which ran a permanent WebGL renderer to show a heading number.
|
|
21
|
-
- **Raspberry Pi Tab**: Temperature, CPU, memory and disk of the machine running the stack, firmware throttling flags and the heaviest processes — the fastest way to see why the boat computer is slow.
|
|
22
|
-
- **GPS-backed Clock**: With no battery on its RTC, the Pi boots with a wrong date after a power cut and no internet, which silently emptied the tide widget. The UI now takes its wall clock from the GPS `navigation.datetime` whenever the system clock is more than a minute off.
|
|
23
|
-
- **No More `NaN` on the Wind**: Every converter in the unit pipeline now rejects non-finite input instead of forwarding `NaN` to the DOM, and the sites that swallowed `NaN` into a silent zero are gone.
|
|
24
|
-
- **Real AIS CPA**: Collision risk is computed from both vessels' course and speed rather than from range alone, so a moored boat abeam is no longer flagged as a hazard.
|
|
25
|
-
- **Depth in the Logbook**, plus manual entries recorded in the same units as the automatic ones.
|
|
27
|
+
## Contents
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
- [Highlights](#highlights)
|
|
30
|
+
- [The 3D view](#the-3d-view)
|
|
31
|
+
- [Traffic and the rules of the road](#traffic-and-the-rules-of-the-road)
|
|
32
|
+
- [Safety: man overboard and anchor watch](#safety-man-overboard-and-anchor-watch)
|
|
33
|
+
- [Instruments and boat systems](#instruments-and-boat-systems)
|
|
34
|
+
- [Offline at sea](#offline-at-sea)
|
|
35
|
+
- [Installation](#installation)
|
|
36
|
+
- [Configuration](#configuration)
|
|
37
|
+
- [Development](#development)
|
|
38
|
+
- [Data sources and credits](#data-sources-and-credits)
|
|
39
|
+
- [Contributing](#contributing) · [Licence](#licence) · [Disclaimer](#navigation-disclaimer)
|
|
28
40
|
|
|
29
41
|
---
|
|
30
42
|
|
|
31
|
-
##
|
|
43
|
+
## Highlights
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| [`@signalk/signalk-autopilot`](https://www.npmjs.com/package/@signalk/signalk-autopilot) | Signal K v2 autopilot API | Autopilot view (which now states explicitly when no provider is registered, instead of showing an inert panel) |
|
|
41
|
-
| [`ocearo-core`](https://www.npmjs.com/package/ocearo-core) | Logbook, anchor, system metrics, AI copilot | Logbook, anchor swing track, Raspberry Pi tab |
|
|
45
|
+
- **A boat you can trim from the screen.** Main, headsails and asymmetric spinnaker drawn from the wind (camber, twist, reefs, sail changes), with draft stripes, telltales and the traveller and jib cars where they should be.
|
|
46
|
+
- **The sea around you, five ways.** A realistic sea built from the true wind, the live chart with buoyage, the seabed in 3D, the wind forecast, or a clean FSD-style ground for racing.
|
|
47
|
+
- **Traffic you can read at a glance.** AIS targets drawn as real ship types and sizes, moving smoothly between reports, coloured by who must give way under COLREG — with the manoeuvre to make.
|
|
48
|
+
- **Tactics.** Laylines to the waypoint, isochrones from your polars (where you will be in 5, 10 and 15 minutes), VMG advice and a polar-speed ghost boat.
|
|
49
|
+
- **Safety first.** Man-overboard marker with drift prediction, anchor watch with the real swing track, shallow-water warnings against your draft.
|
|
50
|
+
- **Everything else on board.** Dashboard, engine and maintenance, energy, tanks, logbook with voyage replay, autopilot, media and documents — in 12 languages, metric, imperial or nautical units, day, dark and red night themes.
|
|
51
|
+
- **Built for the boat.** Works offline once the area is downloaded, adapts to a Raspberry Pi, reads standard Signal K paths only.
|
|
42
52
|
|
|
43
53
|
---
|
|
44
54
|
|
|
45
|
-
##
|
|
55
|
+
## The 3D view
|
|
56
|
+
|
|
57
|
+
The heart of Ocearo is a live 3D scene centred on your boat. A button cycles between five representations of the world around it.
|
|
58
|
+
|
|
59
|
+
| | |
|
|
60
|
+
|---|---|
|
|
61
|
+
|  |  |
|
|
62
|
+
| **Chart.** OpenStreetMap with OpenSeaMap buoyage and lights, true to scale with your boat and the AIS targets. Uses a Signal K chart provider (MBTiles) when one is installed. | **Bathymetry.** The seabed as a survey grid: relief exaggerated, isobaths, soundings at the current tide, a sounder line from the keel, and water too shallow for your draft hatched in orange. 5–20 m SHOM surveys on the French coast, global relief elsewhere. |
|
|
63
|
+
|  |  |
|
|
64
|
+
| **Weather.** The 48-hour wind forecast around the boat (Open-Meteo) in Windy colours, with a time slider. | **Polars and laylines.** Where the polars put you in 5, 10 and 15 minutes on every heading, the laylines to the waypoint and the VMG to steer. |
|
|
65
|
+
|
|
66
|
+
The **sea** itself is generated from the true wind: wave height, length and direction of a coastal wind sea plus a swell, whitecaps from about 7 knots, the sky's reflection and the sun where it really is, and your own wake following the track you actually sailed. The sails are drawn from the apparent wind with their trim: draft stripes with the depth and position of maximum camber, telltales on the luff and leech, and the sheet cars on their tracks.
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
- **Engine Alarms**: The 24 NMEA2000 discrete engine notifications (overheat, oil pressure, coolant level…) are now surfaced with a persistent alarm banner and tab badge, plus configurable temperature zones raising audible SignalK alerts.
|
|
49
|
-
- **Harbor-detail 3D Chart**: Adaptive level-of-detail map plane — pontoons visible at berth (OSM z19 + OpenSeaMap seamarks), wide area when zoomed out, true-to-scale with AIS targets.
|
|
50
|
-
- **Real Weather Map**: Meteo mode combines the base map with the Windy wind overlay and live RainViewer precipitation radar over a ~40 km area.
|
|
51
|
-
- **Living Ocean & Sky**: Wind-driven geometric swell (significant wave height from wind speed), forecast-driven clouds and rain particles, ocean sky shared by all map modes.
|
|
52
|
-
- **Air Quality from VOC**: Dashboard tile driven by the BME680 gas resistance (kΩ) with qualitative scale when no CO₂/PM2.5 sensors are fitted.
|
|
53
|
-
- **Fuel Analytics**: Consumption-range estimation (worst–average), full-tank assumption after refills, engine hours persisted with engine off, complete refill history.
|
|
54
|
-
- **RPi5 Performance**: Chart/meteo modes render a lite ocean without the mirror-reflection pass — the scene is no longer drawn twice per frame.
|
|
55
|
-
- **Previous highlights (v0.1.16)**: full 3D sails with physically-based trim, rigging tensions, sail trim HUD, autopilot view, dashboard, configurable units, Next.js 16 / React 19 / Tailwind v4 stack.
|
|
68
|
+
Boats: a 10.8 m racer (default), a 14 m catamaran and simpler models, chosen in the settings.
|
|
56
69
|
|
|
57
70
|
---
|
|
58
71
|
|
|
59
|
-
##
|
|
72
|
+
## Traffic and the rules of the road
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
| | |
|
|
75
|
+
|---|---|
|
|
76
|
+
|  |  |
|
|
77
|
+
| **Our move.** A vessel engaged in fishing crosses ahead: under rule 18 the sailing yacht keeps clear. The boat and the banner turn orange-red, the advice names the rule and the alteration (“Avoid: 15° to port”). | **Their move.** A port-tack yacht closing from starboard must keep clear (rule 12): it turns violet with the manoeuvre expected of it. If it does not act, rule 17(b) advice appears. |
|
|
78
|
+
|  |  |
|
|
79
|
+
| **Busy water.** Every target carries its role and the rule: the ferry and the cargo ship must keep clear of a yacht under sail (18), the catamaran is to windward on the same tack (12 a-ii), the fishing vessel has right of way. When no single alteration clears everyone, the advice says so and asks to slow down. | **Under engine.** Motoring, the yacht is a power-driven vessel: a cargo ship on the starboard side has right of way (rule 15). The advice passes astern of her (“Avoid: 75° to starboard”) and the dashed line marks the closest point of approach. |
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
- **AIS Radar**: Real-time 3D visualization of nearby vessels with detailed information panels.
|
|
69
|
-
- **Course & Routing**: Dedicated widget for Signal K routes, waypoints, and real-time course calculations.
|
|
70
|
-
- **Environmental Context**: Integrated tide levels, weather forecasts (Signal K Weather API), and depth monitoring with vessel attitude.
|
|
71
|
-
- **Laylines**: High-precision 3D laylines to assist in tactical navigation.
|
|
81
|
+
**The rules Ocearo applies**, from the AIS status and ship type of each target and from our own (a yacht with its engine running is power-driven):
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
| Rule | Situation | Who keeps clear |
|
|
84
|
+
|------|-----------|-----------------|
|
|
85
|
+
| 13 | Overtaking — coming up from more than 22.5° abaft the beam | The overtaking vessel |
|
|
86
|
+
| 18 | Different kinds of vessel | Power ⟶ sail ⟶ fishing ⟶ restricted in her ability to manoeuvre |
|
|
87
|
+
| 12 | Two sailing vessels | Port tack keeps clear of starboard tack; on the same tack, the windward boat |
|
|
88
|
+
| 14 | Head-on between power-driven vessels | Both alter to starboard |
|
|
89
|
+
| 15 | Crossing between power-driven vessels | The one with the other on her starboard side, passing astern |
|
|
90
|
+
| 17 | We are the stand-on vessel | Hold course and speed; may act when the other does not, must act when the give-way vessel alone can no longer avoid collision |
|
|
78
91
|
|
|
79
|
-
|
|
92
|
+
Narrow channels and traffic separation schemes (rules 9–10) are not modelled: the advice is an aid to the watch, never a decision. With **[ocearo-core](https://github.com/laborima/ocearo-core)** on the server, the same rules are also spoken — *“Collision danger: LE PERTUIS at 0.5 miles, CPA 0.1 miles in 6 minutes. Vessel engaged in fishing, we keep clear, rule 18. Pass astern of her, bearing away or slowing down.”* — including rule 19 in restricted visibility, and the AIS layer button switches the banner and advice off with the targets.
|
|
80
93
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
### **Cruising View**
|
|
84
|
-
- **3D Visualization**: Provides a dynamic 3D view of the vessel, displaying critical elements such as:
|
|
85
|
-
- Wind direction with **active laylines**
|
|
86
|
-
- High-precision 3D Compass
|
|
87
|
-
- Depth level & vessel attitude
|
|
88
|
-
- Nearby vessels represented in 3D using AIS data
|
|
89
|
-
- **Sail Trim HUD**: Real-time arc indicators for mainsail traveller and jib cars at compass level.
|
|
90
|
-
- Physically-based sail shape (camber & twist) reflecting current wind conditions.
|
|
91
|
-
|
|
92
|
-

|
|
93
|
-
|
|
94
|
-
### **Anchored View**
|
|
95
|
-
- Simplified 3D representation of the vessel with key at-anchor data, including:
|
|
96
|
-
- GPS position
|
|
97
|
-
- Time
|
|
98
|
-
- Tide levels
|
|
99
|
-
- Depth
|
|
100
|
-
- Battery status
|
|
101
|
-
- Anchor alarm circle centred on the recorded drop point, at the configured radius, with the 80 % watch ring and the rode line
|
|
102
|
-
- **Swing track**: the path travelled around the anchor, so veering, sailing at anchor and the first metres of dragging are visible before any alarm
|
|
103
|
-
|
|
104
|
-

|
|
105
|
-
|
|
106
|
-
### **Park Assist View**
|
|
107
|
-
- Leverages camera and sensor data to simplify docking by:
|
|
108
|
-
- Displaying trajectory predictions based on wind and rudder angle
|
|
109
|
-
- Showing speed indications and live feeds from the front camera
|
|
110
|
-
- Highlighting available berthing spots
|
|
111
|
-
|
|
112
|
-
*Currently in progress.*
|
|
113
|
-
|
|
114
|
-

|
|
115
|
-
|
|
116
|
-
### **Other Views**
|
|
117
|
-
Additional visuals enhance the system's functionality:
|
|
118
|
-
|
|
119
|
-

|
|
120
|
-

|
|
121
|
-

|
|
122
|
-

|
|
123
|
-

|
|
124
|
-

|
|
125
|
-

|
|
126
|
-

|
|
127
|
-

|
|
128
|
-

|
|
129
|
-

|
|
130
|
-

|
|
94
|
+
Colours mean the same thing everywhere: **red** — risk of collision and it is our move; **violet** — risk of collision and it is theirs; **orange** — close but no collision course; grey — nothing to report. CPA and TCPA come from both vessels' course and speed; thresholds are set in the settings. AIS targets are drawn by type and length (sailing yachts, catamarans, ferries, cargo ships, tugs, fishing vessels, lifeboats…) and dead-reckoned between reports, so they glide instead of jumping.
|
|
131
95
|
|
|
132
96
|
---
|
|
133
97
|
|
|
134
|
-
##
|
|
135
|
-
Ocean Robot's roadmap includes advanced features aimed at enhancing safety and efficiency for sailors:
|
|
98
|
+
## Safety: man overboard and anchor watch
|
|
136
99
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- 3D Bathymetry visualization
|
|
142
|
-
- 3D Start lines visualization
|
|
143
|
-
|
|
144
|
-
---
|
|
100
|
+
| | |
|
|
101
|
+
|---|---|
|
|
102
|
+
|  |  |
|
|
103
|
+
| **Man overboard.** One button (or any Signal K MOB notification) raises the alarm: drop point, the person's estimated position now from current and leeway, the drift line and the bearing and distance to steer. | **Anchor watch.** Alarm radius and 80 % watch ring centred on the anchor, the rode, and the track the boat has actually described around it: a veer or a dragging anchor shows in its shape long before the alarm. Kept by [ocearo-core](https://github.com/laborima/ocearo-core), so it survives a reload. |
|
|
145
104
|
|
|
146
|
-
|
|
105
|
+

|
|
147
106
|
|
|
148
|
-
|
|
107
|
+
**Parking assist.** Choose the berth (bow-in, stern-in, alongside, mooring buoy) and follow the predicted track with wind and current.
|
|
149
108
|
|
|
150
109
|
---
|
|
151
110
|
|
|
152
|
-
##
|
|
111
|
+
## Instruments and boat systems
|
|
153
112
|
|
|
154
|
-
|
|
113
|
+
| | |
|
|
114
|
+
|---|---|
|
|
115
|
+
|  |  |
|
|
116
|
+
| **Dashboard.** AIS radar, weather, course to the waypoint, tanks… next to the 3D view, in the day theme… | …and the dark theme, in the spirit of Tesla's FSD display: charcoal, light shapes, luminous accents. |
|
|
117
|
+
|  |  |
|
|
118
|
+
| **Engine.** Speed, hours, temperatures, pressures, gear and alarms (the 24 NMEA 2000 engine notifications), plus a maintenance schedule. | **Energy.** Batteries, charge and consumption, solar, and the health of the Raspberry Pi running the stack. |
|
|
119
|
+
|  |  |
|
|
120
|
+
| **Logbook.** Automatic and manual entries, mission timeline, and recorded voyages you can replay in the 3D view. | **Settings.** Boat, units, language, themes, 3D quality (including a Raspberry Pi profile), alarm thresholds and offline data. |
|
|
155
121
|
|
|
156
|
-
-
|
|
157
|
-
- Suggest features: Share your ideas for new features or improvements your feedback shapes the project!
|
|
158
|
-
- Contribute code: Submit pull requests to add features, fix bugs, or improve documentation.
|
|
159
|
-
- Support the project: Help fund the purchase of webcams, and sensors by buying me a coffee.
|
|
122
|
+

|
|
160
123
|
|
|
161
|
-
|
|
124
|
+
**Night theme.** Red and red-orange only, so the screen keeps your night vision, with values brighter than labels so it stays easy to read. The theme can switch itself with the sun.
|
|
162
125
|
|
|
163
126
|
---
|
|
164
127
|
|
|
165
|
-
##
|
|
128
|
+
## Offline at sea
|
|
166
129
|
|
|
167
|
-
|
|
130
|
+
At sea there is rarely internet. Whenever there is (marina Wi-Fi, 4G), Ocearo keeps what it will need:
|
|
168
131
|
|
|
169
|
-
|
|
132
|
+
- **Chart tiles** you have viewed, **wind forecasts** and **bathymetry** are cached in the display's browser; *Settings → Offline data* downloads the bathymetry and forecast for 5, 10 or 20 NM around the boat in one go.
|
|
133
|
+
- With **[ocearo-core](https://github.com/laborima/ocearo-core)** on the server, the **SHOM surveys** (5–20 m digital elevation models of the French coast, open data) are downloaded by the server itself and shared with every screen on board.
|
|
134
|
+
- OpenStreetMap's tile servers do not allow bulk downloads: for complete offline charts, add MBTiles charts to the Signal K server, which Ocearo then uses automatically.
|
|
170
135
|
|
|
171
|
-
|
|
172
|
-
git clone https://github.com/laborima/ocearo-ui.git
|
|
173
|
-
cd ocearo-ui
|
|
174
|
-
```
|
|
136
|
+
---
|
|
175
137
|
|
|
176
|
-
|
|
138
|
+
## Installation
|
|
177
139
|
|
|
178
|
-
|
|
179
|
-
npm install
|
|
180
|
-
```
|
|
140
|
+
Ocearo UI is a Signal K **webapp**.
|
|
181
141
|
|
|
182
|
-
|
|
142
|
+
1. On your Signal K server (≥ 2.x), open **Appstore → Available**, search for **ocearo-ui** and install it (or `npm install ocearo-ui` in `~/.signalk`).
|
|
143
|
+
2. Restart the server and open `http://<signalk-server>:3000/ocearo-ui/` on any screen on board.
|
|
144
|
+
3. Recommended: install **[ocearo-core](https://github.com/laborima/ocearo-core)** for the logbook, anchor watch, SHOM bathymetry, system metrics and the AI copilot.
|
|
183
145
|
|
|
184
|
-
|
|
185
|
-
npm run dev
|
|
186
|
-
```
|
|
146
|
+
Website: <https://laborima.github.io/ocearo-ui/> · live demo with simulated data: <https://laborima.github.io/ocearo-ui/demo/>
|
|
187
147
|
|
|
188
|
-
|
|
148
|
+
### Signal K prerequisites
|
|
189
149
|
|
|
190
|
-
|
|
150
|
+
Ocearo reads standard Signal K paths; when a path is missing, its display is empty rather than wrong. On a typical NMEA 2000 boat these plugins publish what it needs:
|
|
191
151
|
|
|
192
|
-
|
|
152
|
+
| Plugin | Provides | Used by |
|
|
153
|
+
|--------|----------|---------|
|
|
154
|
+
| [`signalk-derived-data`](https://www.npmjs.com/package/signalk-derived-data) | True wind and true heading (enable `heading`, `angleTrueWater`, `directionTrue`) | Wind, sail trim, polars, compass |
|
|
155
|
+
| [`@meri-imperiumi/signalk-autostate`](https://www.npmjs.com/package/@meri-imperiumi/signalk-autostate) | `navigation.state` | Sail visibility, alert priorities |
|
|
156
|
+
| [`@signalk/set-system-time`](https://www.npmjs.com/package/@signalk/set-system-time) | System clock from GPS | Tides, day/night, logbook |
|
|
157
|
+
| [`@signalk/signalk-autopilot`](https://www.npmjs.com/package/@signalk/signalk-autopilot) | Signal K v2 autopilot API | Autopilot view |
|
|
158
|
+
| [`ocearo-core`](https://github.com/laborima/ocearo-core) | Logbook, anchor, bathymetry, system metrics, AI copilot | Logbook, anchor watch, bathymetry, Raspberry Pi tab |
|
|
193
159
|
|
|
194
|
-
|
|
160
|
+
Hardware: a Raspberry Pi 4 or 5 runs the server and a display comfortably; select the *Raspberry Pi* 3D quality on the Pi's own screen. Any recent browser works as a remote display.
|
|
195
161
|
|
|
196
162
|
---
|
|
197
|
-
### Setup Tides Data
|
|
198
163
|
|
|
199
|
-
|
|
164
|
+
## Configuration
|
|
200
165
|
|
|
201
|
-
|
|
166
|
+
Everything is set in the app (**Settings**): Signal K server address and authentication, boat model, draft and polars, units, language, theme (manual or following the sun), 3D quality, AIS scale and collision thresholds (CPA, TCPA), and offline data. Settings are stored per display.
|
|
202
167
|
|
|
203
|
-
|
|
168
|
+
To install the app on a tablet or phone as a full-screen app (PWA), serve Signal K over HTTPS on the boat's network: see [docs/ssl.md](docs/ssl.md).
|
|
204
169
|
|
|
205
170
|
---
|
|
206
171
|
|
|
207
|
-
##
|
|
208
|
-
|
|
209
|
-
The recommended way is to use the npm published package.
|
|
210
|
-
If you want to deploy your own build:
|
|
172
|
+
## Development
|
|
211
173
|
|
|
212
174
|
```bash
|
|
213
175
|
git clone https://github.com/laborima/ocearo-ui.git
|
|
214
176
|
cd ocearo-ui
|
|
215
177
|
npm install
|
|
216
|
-
|
|
217
|
-
|
|
178
|
+
npm run dev # http://localhost:3000 — point it at your Signal K server in Settings
|
|
179
|
+
npm run lint
|
|
180
|
+
npm run build # static export in out/
|
|
218
181
|
```
|
|
219
182
|
|
|
183
|
+
To try a build on a Signal K server, link it as a webapp: `npm run link` (symlinks `out/` into `~/.signalk/node_modules/ocearo-ui`), then restart the server.
|
|
184
|
+
|
|
185
|
+
Stack: Next.js 16 (static export), React 19, Three.js with React Three Fiber, Tailwind CSS 4, i18next. The 3D boats, sails and AIS fleet are procedural (no model files to download); see [AGENTS.md](AGENTS.md) for the project conventions.
|
|
186
|
+
|
|
187
|
+
Tide tables for offline use live in `public/tides/<harbour>/<MM>_<yyyy>.json`.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Data sources and credits
|
|
192
|
+
|
|
193
|
+
- Charts © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors (ODbL); buoyage © [OpenSeaMap](https://openseamap.org) (CC BY-SA).
|
|
194
|
+
- Bathymetry: [SHOM](https://data.shom.fr) digital elevation models (Licence Ouverte Etalab 2.0), served by ocearo-core; global relief from the [Terrarium tiles](https://registry.opendata.aws/terrain-tiles/) on AWS Open Data (GEBCO, ETOPO, SRTM and others).
|
|
195
|
+
- Wind forecast: [Open-Meteo](https://open-meteo.com) (CC BY 4.0).
|
|
196
|
+
- Sun position: NOAA solar calculator equations.
|
|
197
|
+
|
|
220
198
|
---
|
|
221
199
|
|
|
222
|
-
|
|
200
|
+
## Contributing
|
|
201
|
+
|
|
202
|
+
Bug reports, ideas and pull requests are welcome — see the [issues](https://github.com/laborima/ocearo-ui/issues). Changes are listed in the [CHANGELOG](CHANGELOG.md).
|
|
203
|
+
|
|
204
|
+
[](https://www.buymeacoffee.com/laborima)
|
|
223
205
|
|
|
224
|
-
|
|
206
|
+
## Licence
|
|
225
207
|
|
|
226
|
-
|
|
208
|
+
[Apache 2.0](LICENSE).
|
|
227
209
|
|
|
228
|
-
|
|
229
|
-
- Maintain situational awareness and follow maritime safety regulations.
|
|
230
|
-
- The developers of Ocearo UI are not liable for any incidents, accidents, or navigation errors that may arise from using this software.
|
|
210
|
+
## Navigation disclaimer
|
|
231
211
|
|
|
232
|
-
|
|
212
|
+
Ocearo UI improves situational awareness; it is **not a certified navigation or safety system** and must not be the only source of navigational information. Always cross-check with official charts and instruments, keep a proper lookout and follow the rules of the road. The authors accept no liability for incidents arising from its use.
|
package/__next.__PAGE__.txt
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
|
-
2:I[47257,["/ocearo-ui/_next/static/chunks/
|
|
3
|
-
3:I[81694,["/ocearo-ui/_next/static/chunks/
|
|
4
|
-
6:I[97367,["/ocearo-ui/_next/static/chunks/
|
|
2
|
+
2:I[47257,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"ClientPageRoot"]
|
|
3
|
+
3:I[81694,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js","/ocearo-ui/_next/static/chunks/3q8o52_juxmdp.js","/ocearo-ui/_next/static/chunks/18_i6mf6hb_c7.js","/ocearo-ui/_next/static/chunks/0voiofm58khqd.js","/ocearo-ui/_next/static/chunks/1zm03hw2ylxw8.js","/ocearo-ui/_next/static/chunks/0kpstejrka-7k.js"],"default"]
|
|
4
|
+
6:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"OutletBoundary"]
|
|
5
5
|
7:"$Sreact.suspense"
|
|
6
|
-
|
|
6
|
+
b:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"ViewportBoundary"]
|
|
7
|
+
c:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"MetadataBoundary"]
|
|
8
|
+
d:I[27201,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"IconMark"]
|
|
9
|
+
f:I[39756,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"default"]
|
|
10
|
+
10:I[37457,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"default"]
|
|
11
|
+
:HL["/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","style"]
|
|
12
|
+
a:X
|
|
13
|
+
0:{"buildId":"01VWnAYjs9QwBnnMyWbQF","data":[{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/ocearo-ui/_next/static/chunks/3q8o52_juxmdp.js","async":true}],["$","script","script-1",{"src":"/ocearo-ui/_next/static/chunks/18_i6mf6hb_c7.js","async":true}],["$","script","script-2",{"src":"/ocearo-ui/_next/static/chunks/0voiofm58khqd.js","async":true}],["$","script","script-3",{"src":"/ocearo-ui/_next/static/chunks/1zm03hw2ylxw8.js","async":true}],["$","script","script-4",{"src":"/ocearo-ui/_next/static/chunks/0kpstejrka-7k.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":"$@9","staleTime":"$a","varyParams":null},{"rsc":["$","$1","h",{"children":[null,["$","$Lb",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"}],["$","meta","2",{"name":"theme-color","content":"#f7f8f9","media":"(prefers-color-scheme: light)"}],["$","meta","3",{"name":"theme-color","content":"#101216","media":"(prefers-color-scheme: dark)"}]]}],["$","div",null,{"hidden":true,"children":["$","$Lc",null,{"children":["$","$7",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Ocearo"}],["$","meta","1",{"name":"description","content":"Sailing made smarter"}],["$","link","2",{"rel":"manifest","href":"./manifest.json"}],["$","meta","3",{"name":"format-detection","content":"telephone=no"}],["$","meta","4",{"name":"mobile-web-app-capable","content":"yes"}],["$","meta","5",{"name":"apple-mobile-web-app-title","content":"Ocearo"}],["$","meta","6",{"name":"apple-mobile-web-app-status-bar-style","content":"black-translucent"}],["$","link","7",{"rel":"shortcut icon","href":"./favicon.ico"}],["$","link","8",{"rel":"icon","href":"./favicon.ico","type":"image/x-icon"}],["$","link","9",{"rel":"icon","href":"./favicon.svg","type":"image/svg+xml","sizes":"any"}],["$","link","10",{"rel":"icon","href":"./favicon-96x96.png","type":"image/png","sizes":"96x96"}],["$","link","11",{"rel":"apple-touch-icon","href":"./apple-touch-icon.png"}],["$","$Ld","12",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":"$@e","staleTime":"$a","varyParams":null},{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","precedence":"next"}],["$","script","script-0",{"src":"/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js","async":true}]],["$","html",null,{"lang":"en","children":[["$","head",null,{"children":[["$","meta",null,{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta",null,{"name":"description","content":"Sailing made smarter with Ocearo: touchscreen-first sailing dashboard with navigation, weather, and instrumentation."}]]}],["$","body",null,{"className":"geistsans_fce11f57-module__b_bU6G__variable geistmono_ed61a5f9-module__6fgesq__variable antialiased","children":["$","$Lf",null,{"parallelRouterKey":"children","template":["$","$L10",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]]}]]}],"isPartial":"$@11","staleTime":"$a","varyParams":null}],"isUpgradeableISRFallback":false,"a":"$@12","rootVaryParams":null,"needsRuntimeRequest":"$@13"}
|
|
7
14
|
4:{}
|
|
8
|
-
5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
|
|
15
|
+
5:"$0:data:0:rsc:props:children:0:props:serverProvidedParams:params"
|
|
9
16
|
8:null
|
|
17
|
+
a:300
|
|
18
|
+
13:true
|
|
19
|
+
a:C
|
|
20
|
+
12:0
|
|
21
|
+
e:"$undefined"
|
|
22
|
+
11:"$undefined"
|
|
23
|
+
9:"$undefined"
|
package/__next._full.txt
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
|
-
2:I[39756,["/ocearo-ui/_next/static/chunks/
|
|
3
|
-
3:I[37457,["/ocearo-ui/_next/static/chunks/
|
|
4
|
-
4:I[47257,["/ocearo-ui/_next/static/chunks/
|
|
5
|
-
5:I[81694,["/ocearo-ui/_next/static/chunks/
|
|
6
|
-
8:I[97367,["/ocearo-ui/_next/static/chunks/
|
|
2
|
+
2:I[39756,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"default"]
|
|
3
|
+
3:I[37457,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"default"]
|
|
4
|
+
4:I[47257,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"ClientPageRoot"]
|
|
5
|
+
5:I[81694,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js","/ocearo-ui/_next/static/chunks/3q8o52_juxmdp.js","/ocearo-ui/_next/static/chunks/18_i6mf6hb_c7.js","/ocearo-ui/_next/static/chunks/0voiofm58khqd.js","/ocearo-ui/_next/static/chunks/1zm03hw2ylxw8.js","/ocearo-ui/_next/static/chunks/0kpstejrka-7k.js"],"default"]
|
|
6
|
+
8:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"OutletBoundary"]
|
|
7
7
|
9:"$Sreact.suspense"
|
|
8
|
-
b:I[97367,["/ocearo-ui/_next/static/chunks/
|
|
9
|
-
d:I[97367,["/ocearo-ui/_next/static/chunks/
|
|
10
|
-
f:I[68027,["/ocearo-ui/_next/static/chunks/
|
|
11
|
-
:HL["/ocearo-ui/_next/static/chunks/
|
|
8
|
+
b:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"ViewportBoundary"]
|
|
9
|
+
d:I[97367,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"MetadataBoundary"]
|
|
10
|
+
f:I[68027,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"default",1]
|
|
11
|
+
:HL["/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","style"]
|
|
12
12
|
:HC["/",""]
|
|
13
|
-
0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",
|
|
13
|
+
0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{},"$undefined","$undefined",4608]},"$undefined","$undefined",4624],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":[["$","head",null,{"children":[["$","meta",null,{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta",null,{"name":"description","content":"Sailing made smarter with Ocearo: touchscreen-first sailing dashboard with navigation, weather, and instrumentation."}]]}],["$","body",null,{"className":"geistsans_fce11f57-module__b_bU6G__variable geistmono_ed61a5f9-module__6fgesq__variable antialiased","children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]]}]]}],{"children":[["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@6","$@7"]}}],[["$","script","script-0",{"src":"/ocearo-ui/_next/static/chunks/3q8o52_juxmdp.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/ocearo-ui/_next/static/chunks/18_i6mf6hb_c7.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/ocearo-ui/_next/static/chunks/0voiofm58khqd.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/ocearo-ui/_next/static/chunks/1zm03hw2ylxw8.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/ocearo-ui/_next/static/chunks/0kpstejrka-7k.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$","$9",null,{"name":"Next.MetadataOutlet","children":"$@a"}]}]]}],{},null,false,null]},null,false,null],["$","$1","h",{"children":[null,["$","$Lb",null,{"children":"$Lc"}],["$","div",null,{"hidden":true,"children":["$","$Ld",null,{"children":["$","$9",null,{"name":"Next.Metadata","children":"$Le"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$f",[["$","link","0",{"rel":"stylesheet","href":"/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"r":"$undefined","s":"$undefined","a":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"01VWnAYjs9QwBnnMyWbQF"}
|
|
14
14
|
6:{}
|
|
15
15
|
7:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params"
|
|
16
|
-
c:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}],["$","meta","2",{"name":"theme-color","content":"#
|
|
17
|
-
10:I[27201,["/ocearo-ui/_next/static/chunks/
|
|
16
|
+
c:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"}],["$","meta","2",{"name":"theme-color","content":"#f7f8f9","media":"(prefers-color-scheme: light)"}],["$","meta","3",{"name":"theme-color","content":"#101216","media":"(prefers-color-scheme: dark)"}]]
|
|
17
|
+
10:I[27201,["/ocearo-ui/_next/static/chunks/0h2qsuyze9ds1.js"],"IconMark"]
|
|
18
18
|
a:null
|
|
19
19
|
e:[["$","title","0",{"children":"Ocearo"}],["$","meta","1",{"name":"description","content":"Sailing made smarter"}],["$","link","2",{"rel":"manifest","href":"./manifest.json","crossOrigin":"$undefined"}],["$","meta","3",{"name":"format-detection","content":"telephone=no"}],["$","meta","4",{"name":"mobile-web-app-capable","content":"yes"}],["$","meta","5",{"name":"apple-mobile-web-app-title","content":"Ocearo"}],["$","meta","6",{"name":"apple-mobile-web-app-status-bar-style","content":"black-translucent"}],["$","link","7",{"rel":"shortcut icon","href":"./favicon.ico"}],["$","link","8",{"rel":"icon","href":"./favicon.ico","type":"image/x-icon"}],["$","link","9",{"rel":"icon","href":"./favicon.svg","type":"image/svg+xml","sizes":"any"}],["$","link","10",{"rel":"icon","href":"./favicon-96x96.png","type":"image/png","sizes":"96x96"}],["$","link","11",{"rel":"apple-touch-icon","href":"./apple-touch-icon.png"}],["$","$L10","12",{}]]
|
package/__next._tree.txt
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
:HL["/ocearo-ui/_next/static/chunks/
|
|
1
|
+
:HL["/ocearo-ui/_next/static/chunks/2ryo_bbmt6t74.css","style"]
|
|
2
2
|
:HC["/",""]
|
|
3
|
-
0:{"tree":{"name":"","param":null,"prefetchHints":
|
|
3
|
+
0:{"tree":{"name":"","param":null,"prefetchHints":4176,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":4256,"slots":null}}},"staleTime":300,"buildId":"01VWnAYjs9QwBnnMyWbQF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,28843,t=>{"use strict";var e=t.i(43476),a=t.i(71645),s=t.i(46932),l=t.i(85709);t.s(["default",0,()=>{let t=(0,l.useSignalKPath)("steering.rudderAngle",0),i=(0,a.useMemo)(()=>180*t/Math.PI,[t]);return(0,e.jsx)("div",{style:{width:"400px"},className:"mx-auto p-4 transition-all duration-300 group",children:(0,e.jsxs)("div",{className:"w-full bg-hud-elevated h-1.5 rounded-full relative",children:[(()=>{let t=[];for(let a=-60;a<=60;a+=10){let s=a/120*100;t.push((0,e.jsx)("div",{className:"absolute h-1.5 w-[1px] bg-hud-muted opacity-20",style:{left:`${50+s}%`,bottom:"0"},children:(0,e.jsx)("span",{className:"absolute -top-5 left-1/2 -translate-x-1/2 text-caption font-semibold uppercase tracking-tighter text-hud-muted",children:Math.abs(a)})},a))}return t})(),(0,e.jsx)(s.motion.div,{initial:!1,animate:{width:`${Math.abs(i)/120*100}%`,left:i<0?`${50-Math.abs(i)/120*100}%`:"50%"},transition:{type:"spring",stiffness:300,damping:30},className:`absolute top-0 h-full rounded-full ${i<0?"bg-oRed":"bg-oGreen"} shadow-[0_0_15px_var(--hud-text-main)] shadow-opacity-20`}),(0,e.jsx)("div",{className:"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-1 h-3 bg-hud-muted opacity-20 rounded-full z-10"})]})})}])},50226,function(t){t.n(t.i(28843))}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,28298,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useRouterBFCache",{enumerable:!0,get:function(){return l}});let n=e.r(71645);function l(e,t,r){let[l,u]=(0,n.useState)(()=>({tree:e,cacheNode:t,stateKey:r,next:null}));if(l.tree===e)return l;let a={tree:e,cacheNode:t,stateKey:r,next:null},o=1,d=l,s=a;for(;null!==d&&o<1;){if(d.stateKey===r){s.next=d.next;break}{o++;let e={tree:d.tree,cacheNode:d.cacheNode,stateKey:d.stateKey,next:null};s.next=e,s=e}d=d.next}return u(a),a}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},47257,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientPageRoot",{enumerable:!0,get:function(){return s}});let n=e.r(43476),l=e.r(8372),u=e.r(71645),a=e.r(33906),o=e.r(61994),d=e.r(42903);function s({Component:e,serverProvidedParams:t}){let r,i;if(null!==t)r=t.searchParams,i=t.params;else{let e=(0,u.use)(l.LayoutRouterContext);i=null!==e?e.parentParams:{},r=(0,a.urlSearchParamsToParsedUrlQuery)((0,u.use)(o.SearchParamsContext))}let c=(0,d.createClientSearchParams)(r),f=(0,d.createClientParams)(i);return(0,n.jsx)(e,{params:f,searchParams:c})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},92825,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientSegmentRoot",{enumerable:!0,get:function(){return o}});let n=e.r(43476),l=e.r(8372),u=e.r(71645),a=e.r(42903);function o({Component:e,slots:t,serverProvidedParams:r}){let d;if(null!==r)d=r.params;else{let e=(0,u.use)(l.LayoutRouterContext);d=null!==e?e.parentParams:{}}let s=(0,a.createClientParams)(d);return(0,n.jsx)(e,{...t,params:s})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},68017,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"HTTPAccessFallbackBoundary",{enumerable:!0,get:function(){return i}});let n=e.r(90809),l=e.r(43476),u=n._(e.r(71645)),a=e.r(90373),o=e.r(54394),d=e.r(8372);class s extends u.default.Component{constructor(e){super(e),this.state={triggeredStatus:void 0,previousPathname:e.pathname}}componentDidCatch(){}static getDerivedStateFromError(e){if((0,o.isHTTPAccessFallbackError)(e))return{triggeredStatus:(0,o.getAccessFallbackHTTPStatus)(e)};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.triggeredStatus?{triggeredStatus:void 0,previousPathname:e.pathname}:{triggeredStatus:t.triggeredStatus,previousPathname:e.pathname}}render(){let{notFound:e,forbidden:t,unauthorized:r,children:n}=this.props,{triggeredStatus:u}=this.state,a={[o.HTTPAccessErrorStatus.NOT_FOUND]:e,[o.HTTPAccessErrorStatus.FORBIDDEN]:t,[o.HTTPAccessErrorStatus.UNAUTHORIZED]:r};if(u){let d=u===o.HTTPAccessErrorStatus.NOT_FOUND&&e,s=u===o.HTTPAccessErrorStatus.FORBIDDEN&&t,i=u===o.HTTPAccessErrorStatus.UNAUTHORIZED&&r;return d||s||i?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("meta",{name:"robots",content:"noindex"}),!1,a[u]]}):n}return n}}function i({notFound:e,forbidden:t,unauthorized:r,children:n}){let o=(0,a.useUntrackedPathname)(),c=(0,u.useContext)(d.MissingSlotContext);return e||t||r?(0,l.jsx)(s,{pathname:o,notFound:e,forbidden:t,unauthorized:r,missingSlots:c,children:n}):(0,l.jsx)(l.Fragment,{children:n})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},22976,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return u},PlaceValidationBoundaryBelowThisLevel:function(){return a},RenderValidationBoundaryAtThisLevel:function(){return o},SlotMarker:function(){return d}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let u=null,a=null,o=null,d=null;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},77694,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return u.InstantValidationBoundaryContext},PlaceValidationBoundaryBelowThisLevel:function(){return u.PlaceValidationBoundaryBelowThisLevel},RenderValidationBoundaryAtThisLevel:function(){return u.RenderValidationBoundaryAtThisLevel},SlotMarker:function(){return u.SlotMarker}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let u=e.r(22976);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},39756,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={LoadingBoundaryProvider:function(){return C},default:function(){return T}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let u=e.r(55682),a=e.r(90809),o=e.r(43476),d=a._(e.r(71645)),s=u._(e.r(74080)),i=e.r(8372),c=e.r(1244),f=e.r(72383),p=e.r(91915),y=e.r(58442),m=e.r(68017);e.r(77694);let b=e.r(70725),_=e.r(28298);e.r(74180);let h=e.r(61994),P=e.r(33906),v=e.r(95871);s.default.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function g(e,t,r){let n=e.getClientRects();if(0===n.length)return 0;let l=1/0;for(let e=0;e<n.length;e++){let t=n[e];t.top<l&&(l=t.top)}return l>=r()&&l<=t?1:2}d.default.Component;let j=function(e){let t=d.default.useRef(null);return(0,d.useLayoutEffect)(()=>{let{focusAndScrollRef:r,cacheNode:n}=e,l=r.forceScroll?r.scrollRef:n.scrollRef;if(null===l||!l.current)return;let u=null,a=r.hashFragment;if(a){var o;if(null===(u="top"===(o=a)?document.body:document.getElementById(o)??document.getElementsByName(o)[0]??null)){l.current=!1,r.onlyHashChange=!1,r.hashFragment=null;return}}else u=t.current;if(null===u)return;let d=!1;(0,p.disableSmoothScrollDuringRouteTransition)(()=>{let e=document.documentElement,t=null,r=null,n=null,o=()=>{var r,l;let u,a;return null===n&&(r=e,l=t,n=!Number.isFinite(a=Number.parseFloat(u=getComputedStyle(r).scrollPaddingTop))||a<0?0:u.endsWith("px")?a:u.endsWith("%")?a/100*l:0),n};(a||(t=e.clientHeight,0!==(r=g(u,t,o))))&&((d=!0,l.current=!1,a)?u.scrollIntoView():1!==r&&(e.scrollTop=0,2===g(u,t,o)&&u.scrollIntoView()))},{dontForceLayout:!0,onlyHashChange:r.onlyHashChange}),d&&(r.onlyHashChange=!1,r.hashFragment=null)},void 0),(0,o.jsx)(d.Fragment,{ref:t,children:e.children})};function O({children:e,cacheNode:t}){let r=(0,d.useContext)(i.GlobalLayoutRouterContext);if(!r)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});return(0,o.jsx)(j,{focusAndScrollRef:r.focusAndScrollRef,cacheNode:t,children:e})}function x({tree:e,segmentPath:t,debugNameContext:r,cacheNode:n,params:l,url:u,isActive:a}){let s,f=(0,d.useContext)(i.GlobalLayoutRouterContext);if((0,d.useContext)(h.NavigationPromisesContext),!f)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});let p=null!==n?n:(0,d.use)(c.unresolvedThenable),y=null!==p.prefetchRsc?p.prefetchRsc:p.rsc,m=(0,d.useDeferredValue)(p.rsc,y);if((0,v.isDeferredRsc)(m)){let e=(0,d.use)(m);null===e&&(0,d.use)(c.unresolvedThenable),s=e}else null===m&&(0,d.use)(c.unresolvedThenable),s=m;let b=s;return(0,o.jsx)(i.LayoutRouterContext.Provider,{value:{parentTree:e,parentCacheNode:p,parentSegmentPath:t,parentParams:l,parentLoadingData:null,debugNameContext:r,url:u,isActive:a},children:b})}function C({loading:e,children:t}){let r=(0,d.use)(i.LayoutRouterContext);return null===r?t:(0,o.jsx)(i.LayoutRouterContext.Provider,{value:{parentTree:r.parentTree,parentCacheNode:r.parentCacheNode,parentSegmentPath:r.parentSegmentPath,parentParams:r.parentParams,parentLoadingData:e,debugNameContext:r.debugNameContext,url:r.url,isActive:r.isActive},children:t})}function R({name:e,loading:t,children:r}){if(null!==t){let n=t[0],l=t[1],u=t[2];return(0,o.jsx)(d.Suspense,{name:e,fallback:(0,o.jsxs)(o.Fragment,{children:[l,u,n]}),children:r})}return(0,o.jsx)(o.Fragment,{children:r})}function T({parallelRouterKey:e,error:t,errorStyles:r,errorScripts:n,templateStyles:l,templateScripts:u,template:a,notFound:s,forbidden:p,unauthorized:h,segmentViewBoundaries:v}){let g=(0,d.useContext)(i.LayoutRouterContext);if(!g)throw Object.defineProperty(Error("invariant expected layout router to be mounted"),"__NEXT_ERROR_CODE",{value:"E56",enumerable:!1,configurable:!0});let{parentTree:j,parentCacheNode:C,parentSegmentPath:S,parentParams:M,parentLoadingData:E,url:N,isActive:F,debugNameContext:A}=g,B=j[0],D=null===S?[e]:S.concat([B,e]),L=j[1][e],H=C.slots;(void 0===L||null===H)&&(0,d.use)(c.unresolvedThenable);let w=L[0],k=H[e]??null,U=(0,b.createRouterCacheKey)(w,!0),V=(0,_.useRouterBFCache)(L,k,U),I=[];do{let e=V.tree,d=V.cacheNode,c=V.stateKey,b=e[0],_=M;if(Array.isArray(b)){let e=b[0],t=b[1],r=b[2],n=(0,P.getParamValueFromCacheKey)(t,r);null!==n&&(_={...M,[e]:n})}let v=function(e){if("/"===e)return"/";if("string"==typeof e)if("(__SLOT__)"===e)return;else return e+"/";return e[1]+"/"}(b),g=v??A,j=void 0===v?void 0:A,C=(0,o.jsxs)(O,{cacheNode:d,children:[(0,o.jsx)(f.ErrorBoundary,{errorComponent:t,errorStyles:r,errorScripts:n,children:(0,o.jsx)(R,{name:j,loading:E,children:(0,o.jsx)(m.HTTPAccessFallbackBoundary,{notFound:s,forbidden:p,unauthorized:h,children:(0,o.jsxs)(y.RedirectBoundary,{children:[(0,o.jsx)(x,{url:N,tree:e,params:_,cacheNode:d,segmentPath:D,debugNameContext:g,isActive:F&&c===U}),null]})})})}),null]}),T=(0,o.jsxs)(i.TemplateContext.Provider,{value:C,children:[l,u,a]},c);I.push(T),V=V.next}while(null!==V)return I}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},37457,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return o}});let n=e.r(90809),l=e.r(43476),u=n._(e.r(71645)),a=e.r(8372);function o(){let e=(0,u.useContext)(a.TemplateContext);return(0,l.jsx)(l.Fragment,{children:e})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},6831,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},97689,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(6831).createRenderParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},93504,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},66996,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(93504).createRenderSearchParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},42903,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createClientParams:function(){return u.createRenderParamsFromClient},createClientSearchParams:function(){return a.createRenderSearchParamsFromClient}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let u=e.r(97689),a=e.r(66996);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},27201,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"IconMark",{enumerable:!0,get:function(){return l}});let n=e.r(43476),l=()=>"u">typeof window?null:(0,n.jsx)("meta",{name:"«nxt-icon»"})},91915,(e,t,r)=>{"use strict";function n(e,t={}){if(t.onlyHashChange)return void e();let r=document.documentElement;if("smooth"!==r.dataset.scrollBehavior)return void e();let l=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=l}e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"disableSmoothScrollDuringRouteTransition",{enumerable:!0,get:function(){return n}})}]);
|