signalk-wakelogger 0.2.0-beta.6 → 0.2.0-beta.8

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +13 -3
  3. package/dist/courses/native-course.js +15 -3
  4. package/dist/courses/native-course.js.map +1 -1
  5. package/dist/index.js +430 -6
  6. package/dist/index.js.map +1 -1
  7. package/dist/outbox/database-outbox.js +13 -0
  8. package/dist/outbox/database-outbox.js.map +1 -1
  9. package/dist/race/navigation-control.d.ts +23 -0
  10. package/dist/race/navigation-control.js +63 -0
  11. package/dist/race/navigation-control.js.map +1 -0
  12. package/dist/race/onboard-service.js +6 -1
  13. package/dist/race/onboard-service.js.map +1 -1
  14. package/dist/race/readiness.d.ts +73 -0
  15. package/dist/race/readiness.js +108 -0
  16. package/dist/race/readiness.js.map +1 -0
  17. package/dist/signalk/normaliser.d.ts +1 -0
  18. package/dist/signalk/normaliser.js +12 -1
  19. package/dist/signalk/normaliser.js.map +1 -1
  20. package/dist/telemetry/types.d.ts +18 -0
  21. package/dist/tracking/archive.d.ts +62 -0
  22. package/dist/tracking/archive.js +479 -0
  23. package/dist/tracking/archive.js.map +1 -0
  24. package/dist/tracking/track.d.ts +20 -0
  25. package/dist/tracking/track.js +25 -0
  26. package/dist/tracking/track.js.map +1 -0
  27. package/dist/transport/mqtt-client.d.ts +2 -1
  28. package/dist/transport/mqtt-client.js +12 -0
  29. package/dist/transport/mqtt-client.js.map +1 -1
  30. package/dist/trips/recording-store.d.ts +10 -1
  31. package/dist/trips/recording-store.js +89 -1
  32. package/dist/trips/recording-store.js.map +1 -1
  33. package/docs/course-sync.md +86 -5
  34. package/docs/onboard-race-guidance.md +75 -0
  35. package/package.json +8 -6
  36. package/public/api-client.mjs +157 -15
  37. package/public/app.mjs +595 -79
  38. package/public/course-progress.mjs +24 -3
  39. package/public/index.html +5 -4
  40. package/public/instruments.mjs +215 -0
  41. package/public/navigation-errors.mjs +38 -0
  42. package/public/offline-readiness.mjs +24 -0
  43. package/public/race-plan.mjs +15 -6
  44. package/public/style.css +3 -0
  45. package/public/track.mjs +87 -0
  46. package/public/tracking-controls.mjs +35 -4
  47. package/public/vessel-guides.mjs +50 -0
  48. package/public/wind-derivation.mjs +58 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,74 @@
2
2
 
3
3
  Updates for boat owners and crew: what's new, what's improved, and anything you need to do.
4
4
 
5
+ ## [0.2.0-beta.8] - 2026-10-06
6
+
7
+ ### Finish a trip onboard
8
+
9
+ - A new **Finish trip** control closes the recording cleanly and asks Wake Logger to confirm it on the current connection, so the finished trip is processed and marked ready without waiting for the next reconnect.
10
+ - The onboard recorder keeps serialising samples if persisting a receipt fails, so a momentary storage error cannot stall the upload queue.
11
+
12
+ ### The right course, every time
13
+
14
+ - Wake Logger's own Signal K course is reconciled without treating it as a foreign route, and a newer Race Pack identity is surfaced before the course is delivered, so a previous race's course cannot silently win.
15
+
16
+ ### Guides on the onboard map
17
+
18
+ - True heading and mirrored apparent-wind tack/gybe guides are drawn on the chartplotter, so the tack or gybe angle is visible against the boat's heading.
19
+
20
+ ## [0.2.0-beta.7] - 2026-10-01
21
+
22
+ ### A new recording never shows the previous trip
23
+
24
+ - If a fresh recording starts (or the boat records before a browser connects), the onboard map no longer treats a browser-drawn tail as the whole trip: an empty or failed archive read is reconciled on the next poll, so the full recovered track appears promptly instead of after hundreds of fixes.
25
+ - The map keeps an explicit viewport intent. Fullscreen, rotation, resizing and course changes no longer re-frame the map or drop the selected recording, the archive identity is guarded so a delayed response for a previous recording cannot appear, and a new recording's positions are never appended to the recording still on screen. Fit course, Fit track and Centre on vessel stay separate.
26
+
27
+ ### See the whole trip from wherever you open the map
28
+
29
+ - Opening the onboard map part-way through a passage (or reloading, or connecting a second device) now shows the recorded track from the real departure through the latest position, sourced from the durable onboard archive rather than from page-open time. This works with no internet and with Live tracking off, and it survives a plugin restart without its graceful stop path.
30
+ - A labelled **Fit track** control fits the whole sailed track, independent of any course, and the map automatically fits the full track on first load unless you have already panned or zoomed. Fit course and Centre on vessel stay separate, so course overlays never hide the sailed history.
31
+
32
+ ### Completed trips stay on the map after upload
33
+
34
+ - The onboard map archive keeps its own recording index, independent of the upload queue. A completed trip remains available on the map after its telemetry has been uploaded and acknowledged and after the pending-upload records are removed, and it survives a reload or plugin restart. Starting a new trip never mixes it with the previous one.
35
+ - The archive repairs an interrupted write when it next opens or appends: a partial header is rewritten, a partial final record is trimmed, and a corrupt file is quarantined, so records stay aligned. Writes are ordered and bounded, and pending writes are flushed on orderly shutdown. Power-loss durability is not claimed per sample; the last flushed data is retained and the tail is repaired.
36
+
37
+ ### Navigation can only be advanced by the controlling device
38
+
39
+ - Taking navigation control returns a generation. A permit from the plugin is an authorisation, not an application: `already_applied`/`superseded` are reported only from observed native state, the actual pending detection is validated, and the detection is accepted only after a confirm step re-reads native state. A stale point, changed course, expired/handed-over controller, or missing detection is rejected, and a merely permitted-but-unexecuted attempt stays pending and retryable.
40
+ - Automatic application is disabled in this candidate, because Signal K 2.31 has no plugin point-index API or compare-and-set to fence a client-performed native write. Detections are offered for explicit acceptance by the controlling device. Each browser tab has its own identity, so a newly opened tab is a viewer until someone deliberately takes control.
41
+
42
+ ### Trustworthy instrument values
43
+
44
+ - Every input used by a derived wind or VMG value — including speed over ground/through water and the heading used to convert an apparent angle — now participates in the freshness and time-skew bound, so a stale input cannot be hidden by a fresh one.
45
+ - Signal K request deadlines now stay active while the response body is being read, so a stalled body times out instead of hanging, and the next poll recovers.
46
+
47
+ ### A broken source clock can no longer hide the trip
48
+
49
+ - A source time more than 30 days before the delta was delivered is treated as a broken clock and replaced by receipt time, instead of being queued and later rejected by Wake Logger as outside the vessel's entitled capture window (for example a GPS reporting a stale 2014 default date).
50
+ - The database outbox now declares sequences skipped by a seed or reset as dropped when it opens, matching the file outbox, so the cloud's contiguous acknowledgement can advance and later trips are not left waiting for history.
51
+
52
+ ## [Unreleased] - 2026-09-27
53
+
54
+ ### Offline race readiness you can trust
55
+
56
+ - One clear **Offline race ready** status now checks that the selected course is applied, the expected Signal K route is active, and a Race Pack that matches the course (id, race plan and course definition) is prepared with supported rules and a current forecast. Changing the course immediately invalidates readiness for the old pack, even though that pack is kept for history.
57
+ - Switching Live tracking off stays possible for radio silence, but if readiness is incomplete the app now shows a prominent pre-switch warning that names exactly what is missing instead of implying onboard sail planning will work.
58
+
59
+ ### Clearer navigation failures
60
+
61
+ - Failed Signal K requests now keep the operation, method, path, HTTP status and a bounded, credential-safe reason. Advancing, setting or activating a course shows a human-readable message such as "Could not advance to the next course point to Mark 3 — Signal K rejected the active route update: <reason>", and the bounded detail is written to the plugin log. Tokens and passwords are never logged or displayed.
62
+
63
+ ### A track that survives reload
64
+
65
+ - The onboard map now rebuilds the current recording's track from an independent durable onboard archive on open or reload, rather than starting at page-open time and rather than depending on whether telemetry has already been uploaded. New fixes append incrementally; long trips are decimated for display without changing the recording; and the complete geometry survives browser reload, page-resume and plugin restart with no Wake Logger/cloud connection. A tail-only cloud trip is marked "Reconstructing trip · N% history received" until its history converges.
66
+
67
+ ### Standalone vessel instruments
68
+
69
+ - A new **Instruments** tab is the default when no course is selected. It reads position, speed and course over ground, heading (true or magnetic), speed through water, depth (with its reference), and apparent and true wind directly from the local Signal K server.
70
+ - Instruments are independent of the course, Race Pack, recording and Wake Logger connection: a failed course request, a mismatched pack or Live tracking off does not stop them. Freshness is tracked per measurement, stale and missing values are marked, and no wind is invented from forecast data. Wind-relative VMG is labelled as such.
71
+ - "No course selected" is a normal state: the instrument view stays clean, and course controls and race warnings remain in the race panel.
72
+
5
73
  ## [0.2.0-beta.6] - 2026-09-26
6
74
 
7
75
  ### Onboard race planning matches Wake Logger exactly
package/README.md CHANGED
@@ -45,7 +45,9 @@ You can also choose **Record locally** or **Automatic upload** in the plugin's *
45
45
 
46
46
  On reconnecting, the latest position is sent promptly while stored history uploads in the background. With the supporting Wake Logger service update, your vessel view shows the percentage of stored history uploaded and an estimated time remaining once there is enough upload progress to measure. Estimates pause when the connection is lost. Detailed recording updates are available under **Upload details**. Wake Logger uses the recorded movement and times to identify trips; switching live tracking does not itself create a new trip. Missing or rejected readings are flagged rather than presented as a complete trip.
47
47
 
48
- **Before a long outing:** Check available storage and your queue limits. The default limits are seven days or 250 MB, whichever is reached first. If a limit is reached, the oldest queued readings are discarded; plugin status reports the dropped count. Recording locally controls this plugin's Wake Logger connections only—it does not switch off other apps or your boat's internet access.
48
+ **When you dock:** Tap **Finish trip** before switching off boat power. The plugin saves the trip’s actual final recorded sequence and capture time immediately, including offline and with Live tracking off. **Saved onboard · upload pending** is local success, not cloud confirmation. Keep power and Live tracking on until **Trip confirmed ready by cloud** appears if you need confirmation now; the same connection checks receipt coverage and processing. Otherwise the pending finish survives restart and uploads later. The automatic 15-minute stationary stop remains the fallback. Finish trip does not change the active Signal K route, and fresh movement can start a new recording.
49
+
50
+ **Before a long outing:** Check available storage and your queue limits. The default limits are seven days or 250 MB, whichever is reached first. If a limit is reached, the oldest queued readings are discarded; plugin status reports the dropped count. The dropped count is a **lifetime** total across every upload, not the number lost from the current trip—losses that belong to the current upload are shown separately, and a recording affected by them is marked as not complete. Recording locally controls this plugin's Wake Logger connections only—it does not switch off other apps or your boat's internet access.
49
51
 
50
52
  ## Bring your race course onboard
51
53
 
@@ -53,14 +55,22 @@ Select a saved race course for your vessel in Wake Logger while internet access
53
55
 
54
56
  Open the **Wake Logger webapp** from Signal K's Web Apps list, using a phone, tablet or computer connected to the boat's network. Sign in to Signal K if prompted. Any Signal K user account can view the onboard map; changing live tracking or activating a course requires an account with read/write access.
55
57
 
56
- The onboard map uses the same instrument styling as Wake Logger's live view, adapts to phone and tablet screens, and includes a full-screen view. It shows the complete course, your boat, the next mark and current leg. Distance, bearing, cross-track error, VMG and arrival estimates appear when Signal K can calculate them; unavailable readings are left clearly marked.
58
+ The onboard map uses the same instrument styling as Wake Logger's live view, adapts to phone and tablet screens, and includes a full-screen view. It shows the complete course, your boat, the next mark and current leg. Distance, bearing, cross-track error, VMG and arrival estimates appear when Signal K can calculate them; unavailable readings are left clearly marked. Your recorded track is loaded from durable onboard storage when the page opens and then updated live, so reloading the app mid-passage still shows the whole trip rather than only the track since the page opened.
57
59
 
58
60
  Alongside the map, the webapp shows an **onboard race plan**. While **Live tracking** is on, Wake Logger cloud calculates the remaining race: it starts the current leg from your boat's actual position, samples the downloaded forecast at each leg's estimated time, and accounts for current, so the suggested heading, sail plan and arrival estimate keep up with how the race is actually going. When **Live tracking** is off, the vessel performs the same calculation on board from the Race Pack synchronised before departure, so the plan is still available with no internet access. If no Race Pack has synchronised yet, the map and course still work and the plan is clearly marked as unavailable.
59
61
 
60
- Use **Advance point** to move to the next course point, or select a point and choose **Set point** to correct your progress. Progression is manual in this release: it does not automatically judge start-line crossings, mark roundings, gates or finishes.
62
+ Use **Advance point** to move to the next course point, or select a point and choose **Set point** to correct your progress. When mark detection is set to Automatic, a detected rounding advances only on the device that has explicitly taken **Navigation control**; other phones or tablets stay viewers and never advance the course. Detection suggests or holds when it is unsure, and manual controls always win.
61
63
 
62
64
  Your course is also available as a standard Signal K route for other onboard applications. If another app selects a different active route, Wake Logger shows that state. Choose **Activate Wake Logger course** when you want to return to it.
63
65
 
66
+ Before going offshore, check the onboard app's status. **Offline race ready** means the selected course has been applied, its Signal K route is active (and not reversed), a Race Pack that matches the course is stored with supported rules and a forecast valid now, and onboard sail planning will work with no internet. The app distinguishes a forecast that is merely valid now from one whose declared coverage spans the expected race window, and says so when it cannot confirm the whole window. If anything is missing the app says so; you can still switch Live tracking off for radio silence, but you will see a warning naming what is missing.
67
+
68
+ ## Watch your instruments with no course and no internet
69
+
70
+ Open the **Wake Logger webapp** and choose the **Instruments** tab (the default when no course is selected). It reads directly from your boat's Signal K server and shows position, speed and course over ground, heading (true or magnetic), speed through water, depth (with its stated reference), and apparent and true wind, with units and a clear measured/derived label.
71
+
72
+ Instrument readings are independent of the course, Race Pack, recording and cloud connection. Each reading tracks its own freshness, so a stale sensor is marked with its age while the others stay live, and a missing value is shown as unavailable rather than guessed. Wind-relative VMG is labelled separately from VMG to a waypoint (ground- and water-referenced where available). Viewing instruments on another phone or tablet is read-only by default: it will not activate a course, advance a mark, change upload mode or start a recording.
73
+
64
74
  ## Prepare your map for offline use
65
75
 
66
76
  The onboard map can show your boat and course without internet access. Basemap coverage needs a little preparation:
@@ -51,10 +51,16 @@ class NativeCourseService {
51
51
  const current = (await this.current())?.activeRoute?.href;
52
52
  const target = nativeRouteHref(course.courseId);
53
53
  if (!explicit && current && current !== target) {
54
- if (!previousCourse || current !== nativeRouteHref(previousCourse.courseId))
54
+ // cachedCourse is the accepted desired document, so a failed delivery or
55
+ // restart can already have replaced the previous identity. Establish
56
+ // ownership from the native resource and deterministic ID instead.
57
+ const activeId = current.match(/^\/resources\/routes\/([^/]+)$/)?.[1];
58
+ if (!activeId)
55
59
  return 'conflict';
56
- const previousResource = await this.readRoute(nativeRouteId(previousCourse.courseId));
57
- if (!previousResource || !ownedBy(previousResource, previousCourse.courseId))
60
+ const activeResource = await this.readRoute(activeId);
61
+ const ownedCourseId = activeResource?.feature?.properties?.wakelogger?.courseId;
62
+ if (typeof ownedCourseId !== 'string' || current !== nativeRouteHref(ownedCourseId)
63
+ || !ownedBy(activeResource, ownedCourseId))
58
64
  return 'conflict';
59
65
  }
60
66
  // Replayed desired state must not reset an ongoing native course's progress.
@@ -87,6 +93,12 @@ class NativeCourseService {
87
93
  throw new protocol_1.CourseError('native_routes_unavailable');
88
94
  if (failure.status === 404 || failure.statusCode === 404 || failure.code === 'ENOENT' || /not found/i.test(failure.message ?? ''))
89
95
  return undefined;
96
+ // Signal K 2.31's file-backed resource provider can briefly expose a
97
+ // partial file while its write settles (an empty/incomplete JSON read).
98
+ // Treat that transient state as "not readable yet" so the ensureResource
99
+ // read-back loop retries instead of rejecting the whole course with a 409.
100
+ if (error instanceof SyntaxError || /unexpected end of json|unexpected token|invalid json|not readable|EBUSY|EAGAIN/i.test(failure.message ?? ''))
101
+ return undefined;
90
102
  throw error;
91
103
  }
92
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"native-course.js","sourceRoot":"","sources":["../../src/courses/native-course.ts"],"names":[],"mappings":";;;AAyBA,sCAGC;AACD,0CAAmH;AA7BnH,6CAAwC;AACxC,yCAAiF;AAwBjF,SAAgB,aAAa,CAAC,QAAgB;IAC5C,MAAM,IAAI,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/F,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAA;AACvH,CAAC;AACD,SAAgB,eAAe,CAAC,QAAgB,IAAY,OAAO,qBAAqB,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAA,CAAC,CAAC;AAEnH,MAAa,mBAAmB;IACD;IAA7B,YAA6B,GAAoB;QAApB,QAAG,GAAH,GAAG,CAAiB;IAAG,CAAC;IACrD,SAAS,KAAc,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAA,CAAC,CAAC;IAC/N,KAAK,CAAC,OAAO,KAAmC,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA,CAAC,CAAC;IACxI,KAAK,CAAC,OAAO,CAAC,MAA4B,IAAsB,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,KAAK,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA,CAAC,CAAC;IAEvJ,KAAK,CAAC,cAAc,CAAC,MAA4B;QAC/C,IAAI,CAAC,eAAe,EAAE,CAAA;QACtB,MAAM,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACzC,MAAM,QAAQ,GAAkB;YAC9B,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,sBAAsB,MAAM,CAAC,QAAQ,EAAE;YACvE,OAAO,EAAE;gBACP,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,IAAA,uBAAY,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE;gBACtI,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAA,uBAAY,EAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;aACjO;SACF,CAAA;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QACzC,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,sBAAW,CAAC,uBAAuB,CAAC,CAAA;QACnG,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,OAAM;QACjE,MAAM,IAAI,CAAC,GAAG,CAAC,YAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAA;QAChE,2EAA2E;QAC3E,6EAA6E;QAC7E,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACvC,IAAI,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;mBACzC,IAAI,CAAC,SAAS,CAAE,MAAwB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;mBACvG,MAAwB,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ;gBAAE,OAAM;YACjG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QACzD,CAAC;QACD,MAAM,IAAI,sBAAW,CAAC,gCAAgC,CAAC,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAA4B,EAAE,QAAiB,EAAE,cAAqC;QACnG,IAAI,CAAC,eAAe,EAAE,CAAA;QACtB,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,CAAA;QACzD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YAC/C,IAAI,CAAC,cAAc,IAAI,OAAO,KAAK,eAAe,CAAC,cAAc,CAAC,QAAQ,CAAC;gBAAE,OAAO,UAAU,CAAA;YAC9F,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;YACrF,IAAI,CAAC,gBAAgB,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,cAAc,CAAC,QAAQ,CAAC;gBAAE,OAAO,UAAU,CAAA;QACjG,CAAC;QACD,6EAA6E;QAC7E,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,cAAc,EAAE,QAAQ,KAAK,MAAM,CAAC,QAAQ;YAAE,OAAO,QAAQ,CAAA;QACpG,MAAM,aAAa,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,CAAA;QACrE,MAAM,UAAU,GAAG,OAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC;YACnF,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAc,EAAE,IAAA,uBAAY,EAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC3D,CAAC,CAAC,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAA,uBAAY,EAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC9E,MAAM,IAAI,CAAC,GAAG,CAAC,aAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QAC3E,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,sBAAW,CAAC,+BAA+B,CAAC,CAAA;QACvF,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA6B;QAC5C,IAAI,CAAC,eAAe,EAAE,CAAA;QACtB,IAAI,MAAM,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;YACrE,IAAI,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAiB,EAAE,CAAA;QACxF,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,EAAU;QAChC,IAAI,CAAC;YAAC,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,YAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QAAC,CAAC;QACrE,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,KAAkF,CAAA;YAClG,IAAI,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAAE,MAAM,IAAI,sBAAW,CAAC,2BAA2B,CAAC,CAAA;YAC7G,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,UAAU,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAAE,OAAO,SAAS,CAAA;YACnJ,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IACO,eAAe,KAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAAE,MAAM,IAAI,sBAAW,CAAC,2BAA2B,CAAC,CAAA,CAAC,CAAC;CAC9G;AAtED,kDAsEC;AACD,SAAS,OAAO,CAAC,KAAc,EAAE,QAAgB;IAC/C,MAAM,SAAS,GAAG,KAA+B,CAAA;IACjD,OAAO,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,KAAK,QAAQ,CAAA;AAC1E,CAAC"}
1
+ {"version":3,"file":"native-course.js","sourceRoot":"","sources":["../../src/courses/native-course.ts"],"names":[],"mappings":"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"}