@oicl/openbridge-webcomponents 0.0.20260407101310 → 0.0.20260408055359

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 (73) hide show
  1. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts +3 -0
  2. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
  3. package/dist/building-blocks/instrument-radial/instrument-radial.js +50 -22
  4. package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
  5. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.css.js +88 -78
  6. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.css.js.map +1 -1
  7. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.d.ts +18 -7
  8. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.d.ts.map +1 -1
  9. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.js +122 -21
  10. package/dist/components/sequence-loading-spinner/sequence-loading-spinner.js.map +1 -1
  11. package/dist/navigation-instruments/compass/arrow.d.ts +1 -1
  12. package/dist/navigation-instruments/compass/arrow.d.ts.map +1 -1
  13. package/dist/navigation-instruments/compass/arrow.js +3 -3
  14. package/dist/navigation-instruments/compass/arrow.js.map +1 -1
  15. package/dist/navigation-instruments/compass/compass.d.ts +12 -6
  16. package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
  17. package/dist/navigation-instruments/compass/compass.js +29 -24
  18. package/dist/navigation-instruments/compass/compass.js.map +1 -1
  19. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts +37 -1
  20. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts.map +1 -1
  21. package/dist/navigation-instruments/compass-flat/compass-flat.js +34 -3
  22. package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
  23. package/dist/navigation-instruments/compass-sector/compass-sector.css.js +34 -0
  24. package/dist/navigation-instruments/compass-sector/compass-sector.css.js.map +1 -0
  25. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts +101 -0
  26. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -0
  27. package/dist/navigation-instruments/compass-sector/compass-sector.js +404 -0
  28. package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -0
  29. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.d.ts +15 -2
  30. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.d.ts.map +1 -1
  31. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.js +50 -18
  32. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.js.map +1 -1
  33. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts +40 -6
  34. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts.map +1 -1
  35. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js +40 -47
  36. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js.map +1 -1
  37. package/dist/navigation-instruments/rate-of-turn/rot-renderer.d.ts +63 -0
  38. package/dist/navigation-instruments/rate-of-turn/rot-renderer.d.ts.map +1 -0
  39. package/dist/navigation-instruments/rate-of-turn/rot-renderer.js +211 -0
  40. package/dist/navigation-instruments/rate-of-turn/rot-renderer.js.map +1 -0
  41. package/dist/navigation-instruments/rot-sector/rot-sector.d.ts +10 -4
  42. package/dist/navigation-instruments/rot-sector/rot-sector.d.ts.map +1 -1
  43. package/dist/navigation-instruments/rot-sector/rot-sector.js +13 -3
  44. package/dist/navigation-instruments/rot-sector/rot-sector.js.map +1 -1
  45. package/dist/navigation-instruments/rudder/rudder.d.ts +4 -0
  46. package/dist/navigation-instruments/rudder/rudder.d.ts.map +1 -1
  47. package/dist/navigation-instruments/rudder/rudder.js +55 -19
  48. package/dist/navigation-instruments/rudder/rudder.js.map +1 -1
  49. package/dist/navigation-instruments/watch/advice.d.ts +3 -3
  50. package/dist/navigation-instruments/watch/advice.d.ts.map +1 -1
  51. package/dist/navigation-instruments/watch/advice.js +68 -16
  52. package/dist/navigation-instruments/watch/advice.js.map +1 -1
  53. package/dist/navigation-instruments/watch/tickmark.d.ts +2 -1
  54. package/dist/navigation-instruments/watch/tickmark.d.ts.map +1 -1
  55. package/dist/navigation-instruments/watch/tickmark.js +15 -13
  56. package/dist/navigation-instruments/watch/tickmark.js.map +1 -1
  57. package/dist/navigation-instruments/watch/watch.d.ts +29 -0
  58. package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
  59. package/dist/navigation-instruments/watch/watch.js +256 -44
  60. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  61. package/dist/navigation-instruments/watch-flat/watch-flat.d.ts +29 -1
  62. package/dist/navigation-instruments/watch-flat/watch-flat.d.ts.map +1 -1
  63. package/dist/navigation-instruments/watch-flat/watch-flat.js +162 -17
  64. package/dist/navigation-instruments/watch-flat/watch-flat.js.map +1 -1
  65. package/dist/svghelpers/arc-frame.d.ts +42 -0
  66. package/dist/svghelpers/arc-frame.d.ts.map +1 -0
  67. package/dist/svghelpers/arc-frame.js +123 -0
  68. package/dist/svghelpers/arc-frame.js.map +1 -0
  69. package/package.json +1 -1
  70. package/dist/navigation-instruments/compass/rot.d.ts +0 -4
  71. package/dist/navigation-instruments/compass/rot.d.ts.map +0 -1
  72. package/dist/navigation-instruments/compass/rot.js +0 -11
  73. package/dist/navigation-instruments/compass/rot.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { unsafeCSS, LitElement, html } from "lit";
2
- import { property } from "lit/decorators.js";
2
+ import { property, state } from "lit/decorators.js";
3
3
  import { classMap } from "lit/directives/class-map.js";
4
4
  import { styleMap } from "lit/directives/style-map.js";
5
5
  import { customElement } from "../../decorator.js";
@@ -14,6 +14,10 @@ var __decorateClass = (decorators, target, key, kind) => {
14
14
  if (kind && result) __defProp(target, key, result);
15
15
  return result;
16
16
  };
17
+ const DETERMINATE_MS_PER_PERCENT = 50;
18
+ const DETERMINATE_MIN_DURATION_MS = 1200;
19
+ const DETERMINATE_MAX_DURATION_MS = 9e3;
20
+ const DETERMINATE_START_DELAY_MS = 1e3;
17
21
  var SequenceLoadingSpinnerType = /* @__PURE__ */ ((SequenceLoadingSpinnerType2) => {
18
22
  SequenceLoadingSpinnerType2["indicator"] = "indicator";
19
23
  SequenceLoadingSpinnerType2["indicatorPoint"] = "indicator-point";
@@ -34,15 +38,9 @@ let ObcSequenceLoadingSpinner = class extends LitElement {
34
38
  this.type = "indicator";
35
39
  this.progression = "determinate";
36
40
  this.rotationDurationMs = 1e3;
37
- this.progressPercent = 62.5;
38
- }
39
- get wrapperClasses() {
40
- return {
41
- wrapper: true,
42
- "sequence-loading-spinner": true,
43
- [`type-${this.type}`]: true,
44
- [`progression-${this.progression}`]: true
45
- };
41
+ this.progressPercent = 0;
42
+ this.determinateDisplayPercent = 0;
43
+ this.fillAnimGeneration = 0;
46
44
  }
47
45
  get isButtonType() {
48
46
  return this.type === "button" || this.type === "button-point";
@@ -52,26 +50,126 @@ let ObcSequenceLoadingSpinner = class extends LitElement {
52
50
  return Math.max(100, duration);
53
51
  }
54
52
  get clampedProgressPercent() {
55
- const percent = Number.isFinite(this.progressPercent) ? this.progressPercent : 62.5;
53
+ const percent = Number.isFinite(this.progressPercent) ? this.progressPercent : 0;
56
54
  return Math.min(100, Math.max(0, percent));
57
55
  }
58
- render() {
59
- const style = styleMap({
60
- "--spinner-rotation-duration": `${this.clampedRotationDurationMs}ms`,
61
- "--spinner-progress-deg": `${this.clampedProgressPercent * 3.6}deg`
56
+ get determinateRenderPercent() {
57
+ return this.hasUpdated ? this.determinateDisplayPercent : this.clampedProgressPercent;
58
+ }
59
+ get rootClasses() {
60
+ const isDeterminate = this.progression === "determinate";
61
+ const p = this.determinateRenderPercent;
62
+ return {
63
+ "sequence-loading-spinner": true,
64
+ [`type-${this.type}`]: true,
65
+ [`progression-${this.progression}`]: true,
66
+ "progress-empty": isDeterminate && p <= 0,
67
+ "progress-full": isDeterminate && p >= 100
68
+ };
69
+ }
70
+ get spinnerStyle() {
71
+ if (this.progression === "scanning") {
72
+ return styleMap({
73
+ "--spinner-rotation-duration": `${this.clampedRotationDurationMs}ms`
74
+ });
75
+ }
76
+ const percent = this.determinateRenderPercent;
77
+ return styleMap({
78
+ "--spinner-progress-deg": `${percent * 3.6}deg`
62
79
  });
80
+ }
81
+ disconnectedCallback() {
82
+ this.clearFillAnimation();
83
+ super.disconnectedCallback();
84
+ }
85
+ connectedCallback() {
86
+ super.connectedCallback();
87
+ if (!this.hasUpdated) return;
88
+ if (this.progression !== "determinate") {
89
+ return;
90
+ }
91
+ if (this.clampedProgressPercent >= 100) {
92
+ return;
93
+ }
94
+ this.startDeterminateFillAnimation();
95
+ }
96
+ updated(changed) {
97
+ super.updated(changed);
98
+ if (this.progression === "scanning") {
99
+ this.clearFillAnimation();
100
+ return;
101
+ }
102
+ if (this.progression !== "determinate") {
103
+ return;
104
+ }
105
+ const rerun = ["progressPercent", "progression"].some(
106
+ (k) => changed.has(k)
107
+ );
108
+ if (!rerun) {
109
+ return;
110
+ }
111
+ this.startDeterminateFillAnimation();
112
+ }
113
+ clearFillAnimation() {
114
+ if (this.determinateFillFrame !== void 0) {
115
+ window.cancelAnimationFrame(this.determinateFillFrame);
116
+ }
117
+ this.determinateFillFrame = void 0;
118
+ window.clearTimeout(this.determinateStartDelayTimeout);
119
+ this.determinateStartDelayTimeout = void 0;
120
+ this.fillAnimGeneration++;
121
+ }
122
+ startDeterminateFillAnimation() {
123
+ this.clearFillAnimation();
124
+ const generation = this.fillAnimGeneration;
125
+ const start = this.clampedProgressPercent;
126
+ const remaining = Math.max(0, 100 - start);
127
+ const duration = Math.min(
128
+ DETERMINATE_MAX_DURATION_MS,
129
+ Math.max(
130
+ DETERMINATE_MIN_DURATION_MS,
131
+ remaining * DETERMINATE_MS_PER_PERCENT
132
+ )
133
+ );
134
+ if (start >= 100) {
135
+ this.determinateDisplayPercent = 100;
136
+ return;
137
+ }
138
+ this.determinateDisplayPercent = start;
139
+ let startTime = void 0;
140
+ const tick = () => {
141
+ if (generation !== this.fillAnimGeneration) return;
142
+ const now = performance.now();
143
+ if (startTime === void 0) {
144
+ startTime = now;
145
+ }
146
+ const elapsed = now - startTime;
147
+ const t = Math.min(1, elapsed / Math.max(duration, 1));
148
+ this.determinateDisplayPercent = start + (100 - start) * t;
149
+ if (t < 1) {
150
+ this.determinateFillFrame = window.requestAnimationFrame(tick);
151
+ } else {
152
+ this.determinateFillFrame = void 0;
153
+ this.determinateDisplayPercent = 100;
154
+ }
155
+ };
156
+ this.determinateStartDelayTimeout = window.setTimeout(() => {
157
+ if (generation !== this.fillAnimGeneration) return;
158
+ this.determinateFillFrame = window.requestAnimationFrame(tick);
159
+ }, DETERMINATE_START_DELAY_MS);
160
+ }
161
+ render() {
162
+ const style = this.spinnerStyle;
63
163
  const content = html`
64
164
  <span class="spinner" part="spinner" aria-hidden="true" style=${style}>
65
- <span class="caps" aria-hidden="true">
66
- <span class="cap cap-start" aria-hidden="true"></span>
67
- <span class="cap cap-end" aria-hidden="true"></span>
68
- </span>
165
+ <span class="cap cap-start" aria-hidden="true"></span>
166
+ <span class="cap cap-end" aria-hidden="true"></span>
69
167
  </span>
70
168
  `;
71
169
  return this.isButtonType ? html`
72
170
  <button
73
171
  type="button"
74
- class=${classMap(this.wrapperClasses)}
172
+ class=${classMap(this.rootClasses)}
75
173
  part="wrapper"
76
174
  aria-label="Loading"
77
175
  disabled
@@ -79,7 +177,7 @@ let ObcSequenceLoadingSpinner = class extends LitElement {
79
177
  ${content}
80
178
  </button>
81
179
  ` : html`
82
- <span class=${classMap(this.wrapperClasses)} part="wrapper">
180
+ <span class=${classMap(this.rootClasses)} part="wrapper">
83
181
  ${content}
84
182
  </span>
85
183
  `;
@@ -98,6 +196,9 @@ __decorateClass([
98
196
  __decorateClass([
99
197
  property({ type: Number, attribute: "progress-percent" })
100
198
  ], ObcSequenceLoadingSpinner.prototype, "progressPercent", 2);
199
+ __decorateClass([
200
+ state()
201
+ ], ObcSequenceLoadingSpinner.prototype, "determinateDisplayPercent", 2);
101
202
  ObcSequenceLoadingSpinner = __decorateClass([
102
203
  customElement("obc-sequence-loading-spinner")
103
204
  ], ObcSequenceLoadingSpinner);
@@ -1 +1 @@
1
- {"version":3,"file":"sequence-loading-spinner.js","sources":["../../../src/components/sequence-loading-spinner/sequence-loading-spinner.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {styleMap} from 'lit/directives/style-map.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './sequence-loading-spinner.css?inline';\n\nexport enum SequenceLoadingSpinnerType {\n indicator = 'indicator',\n indicatorPoint = 'indicator-point',\n tag = 'tag',\n tagPoint = 'tag-point',\n button = 'button',\n buttonPoint = 'button-point',\n}\n\nexport enum SequenceLoadingSpinnerProgressionType {\n determinate = 'determinate',\n scanning = 'scanning',\n}\n\n/**\n * `<obc-sequence-loading-spinner>` — circular loading indicator for sequence UI.\n *\n * Overview:\n * A compact spinner used alongside sequence steps, tags, or buttons.\n *\n * Features / Variants:\n * - `type`: `indicator | indicator-point | tag | tag-point | button | button-point`.\n * - `progression`: `determinate | scanning`.\n * - `progress-percent`: number `0–100` (used when `progression=\"determinate\"`).\n * - `rotation-duration-ms`: number in ms (controls spin speed).\n *\n * Usage Guidelines:\n * - Use `type` to match the surrounding element size.\n * - Use `progression=\"determinate\"` when you have progress data.\n *\n * Slots / Content:\n * - None.\n *\n * Events:\n * - None.\n *\n * Best Practices:\n * - Keep `progress-percent` within `0–100` for predictable rendering.\n * - Prefer `scanning` for indefinite loading states.\n *\n * Example:\n * ```html\n * <obc-sequence-loading-spinner\n * type=\"button\"\n * progression=\"determinate\"\n * progress-percent=\"62.5\"\n * rotation-duration-ms=\"1200\"\n * ></obc-sequence-loading-spinner>\n * ```\n *\n * Keywords: sequence, loading, spinner, progress, determinate, scanning.\n */\n@customElement('obc-sequence-loading-spinner')\nexport class ObcSequenceLoadingSpinner extends LitElement {\n @property({type: String}) type: SequenceLoadingSpinnerType =\n SequenceLoadingSpinnerType.indicator;\n @property({type: String}) progression: SequenceLoadingSpinnerProgressionType =\n SequenceLoadingSpinnerProgressionType.determinate;\n @property({type: Number, attribute: 'rotation-duration-ms'})\n rotationDurationMs = 1000;\n @property({type: Number, attribute: 'progress-percent'})\n progressPercent = 62.5;\n\n private get wrapperClasses() {\n return {\n wrapper: true,\n 'sequence-loading-spinner': true,\n [`type-${this.type}`]: true,\n [`progression-${this.progression}`]: true,\n };\n }\n\n private get isButtonType(): boolean {\n return (\n this.type === SequenceLoadingSpinnerType.button ||\n this.type === SequenceLoadingSpinnerType.buttonPoint\n );\n }\n\n private get clampedRotationDurationMs(): number {\n const duration = Number.isFinite(this.rotationDurationMs)\n ? this.rotationDurationMs\n : 1000;\n return Math.max(100, duration);\n }\n\n private get clampedProgressPercent(): number {\n const percent = Number.isFinite(this.progressPercent)\n ? this.progressPercent\n : 62.5;\n return Math.min(100, Math.max(0, percent));\n }\n\n override render() {\n const style = styleMap({\n '--spinner-rotation-duration': `${this.clampedRotationDurationMs}ms`,\n '--spinner-progress-deg': `${this.clampedProgressPercent * 3.6}deg`,\n });\n const content = html`\n <span class=\"spinner\" part=\"spinner\" aria-hidden=\"true\" style=${style}>\n <span class=\"caps\" aria-hidden=\"true\">\n <span class=\"cap cap-start\" aria-hidden=\"true\"></span>\n <span class=\"cap cap-end\" aria-hidden=\"true\"></span>\n </span>\n </span>\n `;\n\n return this.isButtonType\n ? html`\n <button\n type=\"button\"\n class=${classMap(this.wrapperClasses)}\n part=\"wrapper\"\n aria-label=\"Loading\"\n disabled\n >\n ${content}\n </button>\n `\n : html`\n <span class=${classMap(this.wrapperClasses)} part=\"wrapper\">\n ${content}\n </span>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-sequence-loading-spinner': ObcSequenceLoadingSpinner;\n }\n}\n"],"names":["SequenceLoadingSpinnerType","SequenceLoadingSpinnerProgressionType"],"mappings":";;;;;;;;;;;;;;;;AAOO,IAAK,+CAAAA,gCAAL;AACLA,8BAAA,WAAA,IAAY;AACZA,8BAAA,gBAAA,IAAiB;AACjBA,8BAAA,KAAA,IAAM;AACNA,8BAAA,UAAA,IAAW;AACXA,8BAAA,QAAA,IAAS;AACTA,8BAAA,aAAA,IAAc;AANJ,SAAAA;AAAA,GAAA,8BAAA,CAAA,CAAA;AASL,IAAK,0DAAAC,2CAAL;AACLA,yCAAA,aAAA,IAAc;AACdA,yCAAA,UAAA,IAAW;AAFD,SAAAA;AAAA,GAAA,yCAAA,CAAA,CAAA;AA4CL,IAAM,4BAAN,cAAwC,WAAW;AAAA,EAAnD,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,OACxB;AACwB,SAAA,cACxB;AAEF,SAAA,qBAAqB;AAErB,SAAA,kBAAkB;AAAA,EAAA;AAAA,EAElB,IAAY,iBAAiB;AAC3B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,4BAA4B;AAAA,MAC5B,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,MACvB,CAAC,eAAe,KAAK,WAAW,EAAE,GAAG;AAAA,IAAA;AAAA,EAEzC;AAAA,EAEA,IAAY,eAAwB;AAClC,WACE,KAAK,SAAS,YACd,KAAK,SAAS;AAAA,EAElB;AAAA,EAEA,IAAY,4BAAoC;AAC9C,UAAM,WAAW,OAAO,SAAS,KAAK,kBAAkB,IACpD,KAAK,qBACL;AACJ,WAAO,KAAK,IAAI,KAAK,QAAQ;AAAA,EAC/B;AAAA,EAEA,IAAY,yBAAiC;AAC3C,UAAM,UAAU,OAAO,SAAS,KAAK,eAAe,IAChD,KAAK,kBACL;AACJ,WAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,EAC3C;AAAA,EAES,SAAS;AAChB,UAAM,QAAQ,SAAS;AAAA,MACrB,+BAA+B,GAAG,KAAK,yBAAyB;AAAA,MAChE,0BAA0B,GAAG,KAAK,yBAAyB,GAAG;AAAA,IAAA,CAC/D;AACD,UAAM,UAAU;AAAA,sEACkD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvE,WAAO,KAAK,eACR;AAAA;AAAA;AAAA,oBAGY,SAAS,KAAK,cAAc,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,cAKnC,OAAO;AAAA;AAAA,YAGb;AAAA,wBACgB,SAAS,KAAK,cAAc,CAAC;AAAA,cACvC,OAAO;AAAA;AAAA;AAAA,EAGnB;AAGF;AA1Ea,0BAyEK,SAAS,UAAU,cAAc;AAxEvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,0BACe,WAAA,QAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,0BAGe,WAAA,eAAA,CAAA;AAG1B,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,WAAW,wBAAuB;AAAA,GALhD,0BAMX,WAAA,sBAAA,CAAA;AAEA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,WAAW,oBAAmB;AAAA,GAP5C,0BAQX,WAAA,mBAAA,CAAA;AARW,4BAAN,gBAAA;AAAA,EADN,cAAc,8BAA8B;AAAA,GAChC,yBAAA;"}
1
+ {"version":3,"file":"sequence-loading-spinner.js","sources":["../../../src/components/sequence-loading-spinner/sequence-loading-spinner.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport type {PropertyValues} from 'lit';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {styleMap} from 'lit/directives/style-map.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './sequence-loading-spinner.css?inline';\n\nconst DETERMINATE_MS_PER_PERCENT = 50;\nconst DETERMINATE_MIN_DURATION_MS = 1200;\nconst DETERMINATE_MAX_DURATION_MS = 9000;\nconst DETERMINATE_START_DELAY_MS = 1000;\n\nexport enum SequenceLoadingSpinnerType {\n indicator = 'indicator',\n indicatorPoint = 'indicator-point',\n tag = 'tag',\n tagPoint = 'tag-point',\n button = 'button',\n buttonPoint = 'button-point',\n}\n\nexport enum SequenceLoadingSpinnerProgressionType {\n determinate = 'determinate',\n scanning = 'scanning',\n}\n\n/**\n * `<obc-sequence-loading-spinner>` — circular loading indicator for sequence UI.\n *\n * Overview:\n * A compact spinner used alongside sequence steps, tags, or buttons.\n *\n * Features / Variants:\n * - `type`: `indicator | indicator-point | tag | tag-point | button | button-point`.\n * - `progression`: `determinate | scanning`.\n * - `progress-percent`: number `0–100` (used when `progression=\"determinate\"`).\n * - Determinate progression uses a built-in fill animation from the current arc toward full completion.\n * - `rotation-duration-ms`: number in ms (controls spin speed).\n *\n * Usage Guidelines:\n * - Use `type` to match the surrounding element size.\n * - With `progression=\"determinate\"`, the arc starts at 12 o'clock on the ring and grows clockwise.\n * - `progress-percent` is used as the starting offset for the determinate fill. After a short delay, the arc animates smoothly from that start value toward full completion.\n * - Changing `progress-percent` during determinate progression restarts the fill from the new start value.\n *\n * Slots / Content:\n * - None.\n *\n * Events:\n * - None.\n *\n * Best Practices:\n * - Keep `progress-percent` within `0–100` for predictable rendering.\n * - Prefer `scanning` for indefinite loading states.\n *\n * Example:\n * ```html\n * <obc-sequence-loading-spinner\n * type=\"button\"\n * progression=\"determinate\"\n * progress-percent=\"25\"\n * ></obc-sequence-loading-spinner>\n * ```\n */\n@customElement('obc-sequence-loading-spinner')\nexport class ObcSequenceLoadingSpinner extends LitElement {\n @property({type: String}) type: SequenceLoadingSpinnerType =\n SequenceLoadingSpinnerType.indicator;\n @property({type: String}) progression: SequenceLoadingSpinnerProgressionType =\n SequenceLoadingSpinnerProgressionType.determinate;\n @property({type: Number, attribute: 'rotation-duration-ms'})\n rotationDurationMs = 1000;\n @property({type: Number, attribute: 'progress-percent'})\n progressPercent = 0;\n\n @state() private determinateDisplayPercent = 0;\n\n private fillAnimGeneration = 0;\n private determinateFillFrame?: number;\n private determinateStartDelayTimeout?: number;\n\n private get isButtonType(): boolean {\n return (\n this.type === SequenceLoadingSpinnerType.button ||\n this.type === SequenceLoadingSpinnerType.buttonPoint\n );\n }\n\n private get clampedRotationDurationMs(): number {\n const duration = Number.isFinite(this.rotationDurationMs)\n ? this.rotationDurationMs\n : 1000;\n return Math.max(100, duration);\n }\n\n private get clampedProgressPercent(): number {\n const percent = Number.isFinite(this.progressPercent)\n ? this.progressPercent\n : 0;\n return Math.min(100, Math.max(0, percent));\n }\n\n private get determinateRenderPercent(): number {\n return this.hasUpdated\n ? this.determinateDisplayPercent\n : this.clampedProgressPercent;\n }\n\n private get rootClasses() {\n const isDeterminate =\n this.progression === SequenceLoadingSpinnerProgressionType.determinate;\n const p = this.determinateRenderPercent;\n return {\n 'sequence-loading-spinner': true,\n [`type-${this.type}`]: true,\n [`progression-${this.progression}`]: true,\n 'progress-empty': isDeterminate && p <= 0,\n 'progress-full': isDeterminate && p >= 100,\n };\n }\n\n private get spinnerStyle() {\n if (this.progression === SequenceLoadingSpinnerProgressionType.scanning) {\n return styleMap({\n '--spinner-rotation-duration': `${this.clampedRotationDurationMs}ms`,\n });\n }\n const percent = this.determinateRenderPercent;\n return styleMap({\n '--spinner-progress-deg': `${percent * 3.6}deg`,\n });\n }\n\n override disconnectedCallback(): void {\n this.clearFillAnimation();\n super.disconnectedCallback();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasUpdated) return;\n if (\n this.progression !== SequenceLoadingSpinnerProgressionType.determinate\n ) {\n return;\n }\n if (this.clampedProgressPercent >= 100) {\n return;\n }\n this.startDeterminateFillAnimation();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (this.progression === SequenceLoadingSpinnerProgressionType.scanning) {\n this.clearFillAnimation();\n return;\n }\n if (\n this.progression !== SequenceLoadingSpinnerProgressionType.determinate\n ) {\n return;\n }\n const rerun = ['progressPercent', 'progression'].some((k) =>\n changed.has(k)\n );\n if (!rerun) {\n return;\n }\n this.startDeterminateFillAnimation();\n }\n\n private clearFillAnimation(): void {\n if (this.determinateFillFrame !== undefined) {\n window.cancelAnimationFrame(this.determinateFillFrame);\n }\n this.determinateFillFrame = undefined;\n window.clearTimeout(this.determinateStartDelayTimeout);\n this.determinateStartDelayTimeout = undefined;\n this.fillAnimGeneration++;\n }\n\n private startDeterminateFillAnimation(): void {\n this.clearFillAnimation();\n const generation = this.fillAnimGeneration;\n const start = this.clampedProgressPercent;\n const remaining = Math.max(0, 100 - start);\n const duration = Math.min(\n DETERMINATE_MAX_DURATION_MS,\n Math.max(\n DETERMINATE_MIN_DURATION_MS,\n remaining * DETERMINATE_MS_PER_PERCENT\n )\n );\n\n if (start >= 100) {\n this.determinateDisplayPercent = 100;\n return;\n }\n\n this.determinateDisplayPercent = start;\n\n let startTime: number | undefined = undefined;\n const tick = () => {\n if (generation !== this.fillAnimGeneration) return;\n const now = performance.now();\n if (startTime === undefined) {\n startTime = now;\n }\n const elapsed = now - startTime;\n const t = Math.min(1, elapsed / Math.max(duration, 1));\n this.determinateDisplayPercent = start + (100 - start) * t;\n if (t < 1) {\n this.determinateFillFrame = window.requestAnimationFrame(tick);\n } else {\n this.determinateFillFrame = undefined;\n this.determinateDisplayPercent = 100;\n }\n };\n this.determinateStartDelayTimeout = window.setTimeout(() => {\n if (generation !== this.fillAnimGeneration) return;\n this.determinateFillFrame = window.requestAnimationFrame(tick);\n }, DETERMINATE_START_DELAY_MS);\n }\n\n override render() {\n const style = this.spinnerStyle;\n const content = html`\n <span class=\"spinner\" part=\"spinner\" aria-hidden=\"true\" style=${style}>\n <span class=\"cap cap-start\" aria-hidden=\"true\"></span>\n <span class=\"cap cap-end\" aria-hidden=\"true\"></span>\n </span>\n `;\n\n return this.isButtonType\n ? html`\n <button\n type=\"button\"\n class=${classMap(this.rootClasses)}\n part=\"wrapper\"\n aria-label=\"Loading\"\n disabled\n >\n ${content}\n </button>\n `\n : html`\n <span class=${classMap(this.rootClasses)} part=\"wrapper\">\n ${content}\n </span>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-sequence-loading-spinner': ObcSequenceLoadingSpinner;\n }\n}\n"],"names":["SequenceLoadingSpinnerType","SequenceLoadingSpinnerProgressionType"],"mappings":"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"}
@@ -4,5 +4,5 @@ export declare enum ArrowStyle {
4
4
  HDG = "HDG",
5
5
  COG = "COG"
6
6
  }
7
- export declare function arrow(style: ArrowStyle, angle: number, priority?: Priority): SVGTemplateResult | SVGTemplateResult[];
7
+ export declare function arrow(style: ArrowStyle, angle: number, priority?: Priority, radiusOffset?: number): SVGTemplateResult | SVGTemplateResult[];
8
8
  //# sourceMappingURL=arrow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"arrow.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/arrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAM,MAAM,KAAK,CAAC;AAC3C,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAErC,oBAAY,UAAU;IACpB,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AAED,wBAAgB,KAAK,CACnB,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,QAA2B,GACpC,iBAAiB,GAAG,iBAAiB,EAAE,CAiCzC"}
1
+ {"version":3,"file":"arrow.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/arrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAM,MAAM,KAAK,CAAC;AAC3C,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAErC,oBAAY,UAAU;IACpB,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AAED,wBAAgB,KAAK,CACnB,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,QAA2B,EACrC,YAAY,SAAI,GACf,iBAAiB,GAAG,iBAAiB,EAAE,CAiCzC"}
@@ -5,11 +5,11 @@ var ArrowStyle = /* @__PURE__ */ ((ArrowStyle2) => {
5
5
  ArrowStyle2["COG"] = "COG";
6
6
  return ArrowStyle2;
7
7
  })(ArrowStyle || {});
8
- function arrow(style, angle, priority = Priority.regular) {
8
+ function arrow(style, angle, priority = Priority.regular, radiusOffset = 0) {
9
9
  const colorName = priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
10
10
  if (style === "HDG") {
11
11
  return svg`
12
- <g transform="rotate(${angle}) translate(-256, -256)">
12
+ <g transform="rotate(${angle}) translate(-256, ${-256 - radiusOffset})">
13
13
 
14
14
  <path d="M254.654 100.32C255.219 99.1903 256.906 99.2277 257.396 100.433L272.312 137.092L272.388 137.301C273.067 139.455 270.647 141.314 268.676 140.13V140.129L256 132.582L243.323 140.129L243.324 140.13C241.289 141.352 238.777 139.332 239.688 137.092L254.604 100.433L254.654 100.32Z"
15
15
  fill=${colorName} stroke="var(--border-silhouette-color)" stroke-width="1" vector-effect="non-scaling-stroke"/>
@@ -17,7 +17,7 @@ function arrow(style, angle, priority = Priority.regular) {
17
17
  `;
18
18
  } else if (style === "COG") {
19
19
  return svg`
20
- <g transform="rotate(${angle}) translate(-256, -256)">
20
+ <g transform="rotate(${angle}) translate(-256, ${-256 - radiusOffset})">
21
21
  <mask id="path-1-outside-1_133_32856" maskUnits="userSpaceOnUse" x="238" y="99" width="36" height="42" fill="black">
22
22
  <rect fill="white" x="238" y="99" width="36" height="42"/>
23
23
  <path fill-rule="evenodd" clip-rule="evenodd" vector-effect="non-scaling-stroke" d="M256 127.334L265.867 133.192L256 108.941L246.133 133.192L256 127.334ZM255.067 100.621C255.404 99.7929 256.596 99.7929 256.933 100.621L271.849 137.28C272.567 139.046 270.584 140.693 268.933 139.701L256 132L243.067 139.701C241.416 140.693 239.433 139.046 240.151 137.28L255.067 100.621Z"/>
@@ -1 +1 @@
1
- {"version":3,"file":"arrow.js","sources":["../../../src/navigation-instruments/compass/arrow.ts"],"sourcesContent":["import {SVGTemplateResult, svg} from 'lit';\nimport {Priority} from '../types.js';\n\nexport enum ArrowStyle {\n HDG = 'HDG',\n COG = 'COG',\n}\n\nexport function arrow(\n style: ArrowStyle,\n angle: number,\n priority: Priority = Priority.regular\n): SVGTemplateResult | SVGTemplateResult[] {\n const colorName =\n priority === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n\n if (style === ArrowStyle.HDG) {\n return svg`\n <g transform=\"rotate(${angle}) translate(-256, -256)\">\n\n<path d=\"M254.654 100.32C255.219 99.1903 256.906 99.2277 257.396 100.433L272.312 137.092L272.388 137.301C273.067 139.455 270.647 141.314 268.676 140.13V140.129L256 132.582L243.323 140.129L243.324 140.13C241.289 141.352 238.777 139.332 239.688 137.092L254.604 100.433L254.654 100.32Z\"\n fill=${colorName} stroke=\"var(--border-silhouette-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>\n </g>\n `;\n } else if (style === ArrowStyle.COG) {\n return svg`\n <g transform=\"rotate(${angle}) translate(-256, -256)\">\n<mask id=\"path-1-outside-1_133_32856\" maskUnits=\"userSpaceOnUse\" x=\"238\" y=\"99\" width=\"36\" height=\"42\" fill=\"black\">\n<rect fill=\"white\" x=\"238\" y=\"99\" width=\"36\" height=\"42\"/>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" vector-effect=\"non-scaling-stroke\" d=\"M256 127.334L265.867 133.192L256 108.941L246.133 133.192L256 127.334ZM255.067 100.621C255.404 99.7929 256.596 99.7929 256.933 100.621L271.849 137.28C272.567 139.046 270.584 140.693 268.933 139.701L256 132L243.067 139.701C241.416 140.693 239.433 139.046 240.151 137.28L255.067 100.621Z\"/>\n</mask>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M256 127.334L265.867 133.192L256 108.941L246.133 133.192L256 127.334ZM255.067 100.621C255.404 99.7929 256.596 99.7929 256.933 100.621L271.849 137.28C272.567 139.046 270.584 140.693 268.933 139.701L256 132L243.067 139.701C241.416 140.693 239.433 139.046 240.151 137.28L255.067 100.621Z\"\n fill=${colorName} />\n<path d=\"M256 127.334L256.511 126.474L256 126.171L255.489 126.474L256 127.334ZM265.867 133.192L265.357 134.052L267.914 135.571L266.793 132.816L265.867 133.192ZM256 108.941L256.926 108.564L256 106.288L255.074 108.564L256 108.941ZM246.133 133.192L245.207 132.816L244.086 135.571L246.643 134.052L246.133 133.192ZM255.067 100.621L254.14 100.244L255.067 100.621ZM256.933 100.621L257.86 100.244L256.933 100.621ZM271.849 137.28L270.922 137.657L271.849 137.28ZM268.933 139.701L269.448 138.844L269.445 138.842L268.933 139.701ZM256 132L256.512 131.141L256 130.836L255.488 131.141L256 132ZM243.067 139.701L242.555 138.842L242.552 138.844L243.067 139.701ZM240.151 137.28L241.078 137.657L240.151 137.28ZM255.489 128.193L265.357 134.052L266.378 132.333L256.511 126.474L255.489 128.193ZM266.793 132.816L256.926 108.564L255.074 109.318L264.941 133.569L266.793 132.816ZM255.074 108.564L245.207 132.816L247.059 133.569L256.926 109.318L255.074 108.564ZM246.643 134.052L256.511 128.193L255.489 126.474L245.622 132.333L246.643 134.052ZM255.993 100.998C255.994 100.994 255.996 100.992 255.996 100.992C255.996 100.992 255.995 100.993 255.994 100.994C255.991 100.997 255.988 101 255.986 101.002C255.984 101.003 255.984 101.002 255.987 101.002C255.99 101.001 255.994 101 256 101C256.006 101 256.01 101.001 256.013 101.002C256.016 101.002 256.016 101.003 256.014 101.002C256.012 101 256.009 100.997 256.006 100.994C256.005 100.993 256.004 100.992 256.004 100.992C256.004 100.992 256.006 100.994 256.007 100.998L257.86 100.244C257.185 98.5852 254.815 98.5852 254.14 100.244L255.993 100.998ZM256.007 100.998L270.922 137.657L272.775 136.903L257.86 100.244L256.007 100.998ZM270.922 137.657C271.255 138.473 270.33 139.373 269.448 138.844L268.418 140.558C270.838 142.012 273.879 139.618 272.775 136.903L270.922 137.657ZM269.445 138.842L256.512 131.141L255.488 132.859L268.422 140.56L269.445 138.842ZM255.488 131.141L242.555 138.842L243.578 140.56L256.512 132.859L255.488 131.141ZM242.552 138.844C241.67 139.373 240.745 138.473 241.078 137.657L239.225 136.903C238.121 139.618 241.162 142.012 243.582 140.558L242.552 138.844ZM241.078 137.657L255.993 100.998L254.14 100.244L239.225 136.903L241.078 137.657Z\" \nfill=\"var(--border-silhouette-color)\" vector-effect=\"non-scaling-stroke\" mask=\"url(#path-1-outside-1_133_32856)\"/>\n\n </g>\n `;\n } else {\n return [];\n }\n\n // return [...shaft, circle, arrowTip];\n}\n"],"names":["ArrowStyle"],"mappings":";;AAGO,IAAK,+BAAAA,gBAAL;AACLA,cAAA,KAAA,IAAM;AACNA,cAAA,KAAA,IAAM;AAFI,SAAAA;AAAA,GAAA,cAAA,CAAA,CAAA;AAKL,SAAS,MACd,OACA,OACA,WAAqB,SAAS,SACW;AACzC,QAAM,YACJ,aAAa,SAAS,WAClB,+CACA;AAEN,MAAI,UAAU,OAAgB;AAC5B,WAAO;AAAA,6BACkB,KAAK;AAAA;AAAA;AAAA,QAG1B,SAAS;AAAA;AAAA;AAAA,EAGf,WAAW,UAAU,OAAgB;AACnC,WAAO;AAAA,6BACkB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMxB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,OAAO;AACL,WAAO,CAAA;AAAA,EACT;AAGF;"}
1
+ {"version":3,"file":"arrow.js","sources":["../../../src/navigation-instruments/compass/arrow.ts"],"sourcesContent":["import {SVGTemplateResult, svg} from 'lit';\nimport {Priority} from '../types.js';\n\nexport enum ArrowStyle {\n HDG = 'HDG',\n COG = 'COG',\n}\n\nexport function arrow(\n style: ArrowStyle,\n angle: number,\n priority: Priority = Priority.regular,\n radiusOffset = 0\n): SVGTemplateResult | SVGTemplateResult[] {\n const colorName =\n priority === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n\n if (style === ArrowStyle.HDG) {\n return svg`\n <g transform=\"rotate(${angle}) translate(-256, ${-256 - radiusOffset})\">\n\n<path d=\"M254.654 100.32C255.219 99.1903 256.906 99.2277 257.396 100.433L272.312 137.092L272.388 137.301C273.067 139.455 270.647 141.314 268.676 140.13V140.129L256 132.582L243.323 140.129L243.324 140.13C241.289 141.352 238.777 139.332 239.688 137.092L254.604 100.433L254.654 100.32Z\"\n fill=${colorName} stroke=\"var(--border-silhouette-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>\n </g>\n `;\n } else if (style === ArrowStyle.COG) {\n return svg`\n <g transform=\"rotate(${angle}) translate(-256, ${-256 - radiusOffset})\">\n<mask id=\"path-1-outside-1_133_32856\" maskUnits=\"userSpaceOnUse\" x=\"238\" y=\"99\" width=\"36\" height=\"42\" fill=\"black\">\n<rect fill=\"white\" x=\"238\" y=\"99\" width=\"36\" height=\"42\"/>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" vector-effect=\"non-scaling-stroke\" d=\"M256 127.334L265.867 133.192L256 108.941L246.133 133.192L256 127.334ZM255.067 100.621C255.404 99.7929 256.596 99.7929 256.933 100.621L271.849 137.28C272.567 139.046 270.584 140.693 268.933 139.701L256 132L243.067 139.701C241.416 140.693 239.433 139.046 240.151 137.28L255.067 100.621Z\"/>\n</mask>\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M256 127.334L265.867 133.192L256 108.941L246.133 133.192L256 127.334ZM255.067 100.621C255.404 99.7929 256.596 99.7929 256.933 100.621L271.849 137.28C272.567 139.046 270.584 140.693 268.933 139.701L256 132L243.067 139.701C241.416 140.693 239.433 139.046 240.151 137.28L255.067 100.621Z\"\n fill=${colorName} />\n<path d=\"M256 127.334L256.511 126.474L256 126.171L255.489 126.474L256 127.334ZM265.867 133.192L265.357 134.052L267.914 135.571L266.793 132.816L265.867 133.192ZM256 108.941L256.926 108.564L256 106.288L255.074 108.564L256 108.941ZM246.133 133.192L245.207 132.816L244.086 135.571L246.643 134.052L246.133 133.192ZM255.067 100.621L254.14 100.244L255.067 100.621ZM256.933 100.621L257.86 100.244L256.933 100.621ZM271.849 137.28L270.922 137.657L271.849 137.28ZM268.933 139.701L269.448 138.844L269.445 138.842L268.933 139.701ZM256 132L256.512 131.141L256 130.836L255.488 131.141L256 132ZM243.067 139.701L242.555 138.842L242.552 138.844L243.067 139.701ZM240.151 137.28L241.078 137.657L240.151 137.28ZM255.489 128.193L265.357 134.052L266.378 132.333L256.511 126.474L255.489 128.193ZM266.793 132.816L256.926 108.564L255.074 109.318L264.941 133.569L266.793 132.816ZM255.074 108.564L245.207 132.816L247.059 133.569L256.926 109.318L255.074 108.564ZM246.643 134.052L256.511 128.193L255.489 126.474L245.622 132.333L246.643 134.052ZM255.993 100.998C255.994 100.994 255.996 100.992 255.996 100.992C255.996 100.992 255.995 100.993 255.994 100.994C255.991 100.997 255.988 101 255.986 101.002C255.984 101.003 255.984 101.002 255.987 101.002C255.99 101.001 255.994 101 256 101C256.006 101 256.01 101.001 256.013 101.002C256.016 101.002 256.016 101.003 256.014 101.002C256.012 101 256.009 100.997 256.006 100.994C256.005 100.993 256.004 100.992 256.004 100.992C256.004 100.992 256.006 100.994 256.007 100.998L257.86 100.244C257.185 98.5852 254.815 98.5852 254.14 100.244L255.993 100.998ZM256.007 100.998L270.922 137.657L272.775 136.903L257.86 100.244L256.007 100.998ZM270.922 137.657C271.255 138.473 270.33 139.373 269.448 138.844L268.418 140.558C270.838 142.012 273.879 139.618 272.775 136.903L270.922 137.657ZM269.445 138.842L256.512 131.141L255.488 132.859L268.422 140.56L269.445 138.842ZM255.488 131.141L242.555 138.842L243.578 140.56L256.512 132.859L255.488 131.141ZM242.552 138.844C241.67 139.373 240.745 138.473 241.078 137.657L239.225 136.903C238.121 139.618 241.162 142.012 243.582 140.558L242.552 138.844ZM241.078 137.657L255.993 100.998L254.14 100.244L239.225 136.903L241.078 137.657Z\" \nfill=\"var(--border-silhouette-color)\" vector-effect=\"non-scaling-stroke\" mask=\"url(#path-1-outside-1_133_32856)\"/>\n\n </g>\n `;\n } else {\n return [];\n }\n\n // return [...shaft, circle, arrowTip];\n}\n"],"names":["ArrowStyle"],"mappings":";;AAGO,IAAK,+BAAAA,gBAAL;AACLA,cAAA,KAAA,IAAM;AACNA,cAAA,KAAA,IAAM;AAFI,SAAAA;AAAA,GAAA,cAAA,CAAA,CAAA;AAKL,SAAS,MACd,OACA,OACA,WAAqB,SAAS,SAC9B,eAAe,GAC0B;AACzC,QAAM,YACJ,aAAa,SAAS,WAClB,+CACA;AAEN,MAAI,UAAU,OAAgB;AAC5B,WAAO;AAAA,6BACkB,KAAK,qBAAqB,OAAO,YAAY;AAAA;AAAA;AAAA,QAGlE,SAAS;AAAA;AAAA;AAAA,EAGf,WAAW,UAAU,OAAgB;AACnC,WAAO;AAAA,6BACkB,KAAK,qBAAqB,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMhE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjB,OAAO;AACL,WAAO,CAAA;AAAA,EACT;AAGF;"}
@@ -1,8 +1,9 @@
1
1
  import { LitElement, PropertyValues } from 'lit';
2
2
  import { AngleAdvice } from '../watch/advice.js';
3
- import { VesselImage } from '../watch/watch.js';
3
+ import { VesselImage, RotType, RotPosition } from '../watch/watch.js';
4
4
  import { InstrumentState, Priority } from '../types.js';
5
5
  import '../watch/watch.js';
6
+ export { RotType };
6
7
  export declare enum CompassDirection {
7
8
  NorthUp = "northUp",
8
9
  HeadingUp = "headingUp",
@@ -37,7 +38,10 @@ export declare enum CompassPriorityElement {
37
38
  * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs;
38
39
  * triggered state is derived from whether the current heading falls
39
40
  * inside the advice range.
40
- * - **Rate of turn**: Animated ROT dot driven by `rotationsPerMinute`.
41
+ * - **Rate of turn**: Animated ROT indicator driven by `rotationsPerMinute`.
42
+ * Supports spinning dots (`rotType="dots"`) and a banana-shaped arc bar
43
+ * (`rotType="bar"`) showing the HDG→COG span. Position on the outer
44
+ * scale ring or inner circle via `rotPosition`.
41
45
  * - **Environmental overlays**: Wind speed/direction and current
42
46
  * speed/direction indicators on the watch face.
43
47
  * - **Vessel image**: Configurable vessel silhouette centered on the
@@ -84,6 +88,8 @@ export declare enum CompassPriorityElement {
84
88
  * @property {number | null} currentFromDirection - The direction the current is coming from in degrees.
85
89
  * @property {VesselImage} vesselImage - The image of the vessel.
86
90
  * @property {number} rotationsPerMinute - The number of rotations per minute for the rate of turn controller.
91
+ * @property {RotType} rotType - ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (arc bar from HDG to COG).
92
+ * @property {RotPosition} rotPosition - ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring).
87
93
  * @property {Priority} priority - Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette.
88
94
  *
89
95
  * @ignition-base-height: 512px
@@ -108,6 +114,10 @@ export declare class ObcCompass extends LitElement {
108
114
  currentFromDirection: number | null;
109
115
  vesselImage: VesselImage;
110
116
  rotationsPerMinute: number;
117
+ rotType: RotType;
118
+ rotPosition: RotPosition;
119
+ rotMaxValue: number;
120
+ rotArcExtent: number;
111
121
  direction: CompassDirection;
112
122
  state: InstrumentState;
113
123
  priority: Priority;
@@ -116,13 +126,9 @@ export declare class ObcCompass extends LitElement {
116
126
  showLabels: boolean;
117
127
  /** When true, labels and north arrow are placed inside the outer ring. */
118
128
  tickmarksInside: boolean;
119
- protected updated(_changedProperties: PropertyValues): void;
120
129
  private _headingSp;
121
130
  willUpdate(changed: PropertyValues): void;
122
131
  disconnectedCallback(): void;
123
- private rot;
124
- private rateOfTurnController?;
125
- firstUpdated(): void;
126
132
  private _resizeController;
127
133
  private getPadding;
128
134
  private get angleAdviceRaw();
@@ -1 +1 @@
1
- {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAY,MAAM,KAAK,CAAC;AAE1D,OAAO,mBAAmB,CAAC;AAG3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAC,WAAW,EAAmC,MAAM,mBAAmB,CAAC;AAKhF,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAEtD,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;CACtB;AAED,oBAAY,sBAAsB;IAChC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,qBACa,UAAW,SAAQ,UAAU;IACd,OAAO,SAAK;IACZ,gBAAgB,SAAK;IAErB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,iBAAiB,EAAE,OAAO,CAAS;IACpC,6BAA6B,EAAE,MAAM,CAAO;IAC3C,uBAAuB,EAAE,OAAO,CAAS;IACvB,qBAAqB,EAAE,OAAO,CACpE;IACmB,6BAA6B,EAAE,MAAM,CAAK;IACzC,eAAe,EAAE,OAAO,CAAS;IACjC,QAAQ,EAAE,OAAO,CAAS;IACV,cAAc,EAAE,WAAW,EAAE,CAAM;IACpD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,WAAW,EAAE,WAAW,CAA0B;IAClD,kBAAkB,EAAE,MAAM,CAAK;IAC/B,SAAS,EAAE,gBAAgB,CAC1B;IACD,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,sBAAsB,EAAE,CAAgC;IAC1E,gDAAgD;IACrB,UAAU,EAAE,OAAO,CAAS;IACvD,0EAA0E;IAC/C,eAAe,EAAE,OAAO,CAAS;cAEzC,OAAO,CAAC,kBAAkB,EAAE,cAAc,GAAG,IAAI;IAUpE,OAAO,CAAC,UAAU,CAGf;IAEM,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAezC,oBAAoB,IAAI,IAAI;IAMrC,OAAO,CAAC,GAAG,CAAe;IAE1B,OAAO,CAAC,oBAAoB,CAAC,CAAuB;IAE3C,YAAY;IAUrB,OAAO,CAAC,iBAAiB,CAAkC;IAE3D,OAAO,CAAC,UAAU;IAclB,OAAO,KAAK,cAAc,GAUzB;IAED,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,WAAW;IAWV,MAAM;IAiEf,OAAgB,MAAM,0BAwBpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAY,MAAM,KAAK,CAAC;AAE1D,OAAO,mBAAmB,CAAC;AAG3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EACL,WAAW,EAGX,OAAO,EACP,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,OAAO,EAAC,CAAC;AAEjB,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;CACtB;AAED,oBAAY,sBAAsB;IAChC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,qBACa,UAAW,SAAQ,UAAU;IACd,OAAO,SAAK;IACZ,gBAAgB,SAAK;IAErB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,iBAAiB,EAAE,OAAO,CAAS;IACpC,6BAA6B,EAAE,MAAM,CAAO;IAC3C,uBAAuB,EAAE,OAAO,CAAS;IACvB,qBAAqB,EAAE,OAAO,CACpE;IACmB,6BAA6B,EAAE,MAAM,CAAK;IACzC,eAAe,EAAE,OAAO,CAAS;IACjC,QAAQ,EAAE,OAAO,CAAS;IACV,cAAc,EAAE,WAAW,EAAE,CAAM;IACpD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,WAAW,EAAE,WAAW,CAA0B;IAClD,kBAAkB,EAAE,MAAM,CAAK;IAC/B,OAAO,EAAE,OAAO,CAAgB;IAChC,WAAW,EAAE,WAAW,CAA2B;IACnD,WAAW,EAAE,MAAM,CAAM;IACzB,YAAY,EAAE,MAAM,CAAM;IAC1B,SAAS,EAAE,gBAAgB,CAC1B;IACD,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,sBAAsB,EAAE,CAAgC;IAC1E,gDAAgD;IACrB,UAAU,EAAE,OAAO,CAAS;IACvD,0EAA0E;IAC/C,eAAe,EAAE,OAAO,CAAS;IAE5D,OAAO,CAAC,UAAU,CAGf;IAEM,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAezC,oBAAoB,IAAI,IAAI;IAOrC,OAAO,CAAC,iBAAiB,CAAkC;IAE3D,OAAO,CAAC,UAAU;IAclB,OAAO,KAAK,cAAc,GAUzB;IAED,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,WAAW;IAWV,MAAM;IAyEf,OAAgB,MAAM,0BAwBpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
@@ -1,16 +1,15 @@
1
1
  import { css, LitElement, html } from "lit";
2
- import { property, query } from "lit/decorators.js";
2
+ import { property } from "lit/decorators.js";
3
3
  import { WatchCircleType } from "../watch/watch.js";
4
4
  import { TickmarkType } from "../watch/tickmark.js";
5
5
  import { arrow, ArrowStyle } from "./arrow.js";
6
6
  import { AdviceState } from "../watch/advice.js";
7
7
  import { ResizeController } from "@lit-labs/observers/resize-controller.js";
8
8
  import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
9
- import { rot } from "./rot.js";
10
- import { RateOfTurnController } from "../rate-of-turn/rate-of-turn.controller.js";
11
9
  import { customElement } from "../../decorator.js";
12
10
  import { InstrumentState, Priority } from "../types.js";
13
11
  import { VesselImage, VesselImageSize } from "../watch/vessel.js";
12
+ import { RotType, RotPosition } from "../rate-of-turn/rot-renderer.js";
14
13
  var __defProp = Object.defineProperty;
15
14
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
16
15
  var __decorateClass = (decorators, target, key, kind) => {
@@ -55,6 +54,10 @@ let ObcCompass = class extends LitElement {
55
54
  this.currentFromDirection = null;
56
55
  this.vesselImage = VesselImage.genericTop;
57
56
  this.rotationsPerMinute = 1;
57
+ this.rotType = RotType.dots;
58
+ this.rotPosition = RotPosition.innerCircle;
59
+ this.rotMaxValue = 10;
60
+ this.rotArcExtent = 60;
58
61
  this.direction = "northUp";
59
62
  this.state = InstrumentState.active;
60
63
  this.priority = Priority.regular;
@@ -70,12 +73,6 @@ let ObcCompass = class extends LitElement {
70
73
  });
71
74
  this._resizeController = new ResizeController(this, {});
72
75
  }
73
- updated(_changedProperties) {
74
- super.updated(_changedProperties);
75
- if (_changedProperties.has("rotationsPerMinute") && this.rateOfTurnController) {
76
- this.rateOfTurnController.rotationsPerMinute = this.rotationsPerMinute;
77
- }
78
- }
79
76
  willUpdate(changed) {
80
77
  super.willUpdate(changed);
81
78
  this._headingSp.sync({
@@ -94,13 +91,6 @@ let ObcCompass = class extends LitElement {
94
91
  super.disconnectedCallback();
95
92
  this._headingSp.dispose();
96
93
  }
97
- firstUpdated() {
98
- this.rateOfTurnController = new RateOfTurnController(
99
- this,
100
- this.rot,
101
- this.rotationsPerMinute
102
- );
103
- }
104
94
  getPadding() {
105
95
  const size = Math.min(this.clientHeight, this.clientWidth);
106
96
  const deltaWidth = 512 - size;
@@ -186,6 +176,15 @@ let ObcCompass = class extends LitElement {
186
176
  /* current */
187
177
  )}
188
178
  .rotation=${this.getRotation()}
179
+ .rotType=${this.rotType}
180
+ .rotPosition=${this.rotPosition}
181
+ .rotStartAngle=${this.heading + (this.getRotation() ?? 0)}
182
+ .rotEndAngle=${this.heading + this.rotationsPerMinute / (this.rotMaxValue || 1) * this.rotArcExtent + (this.getRotation() ?? 0)}
183
+ .rotPriority=${this.priorityFor(
184
+ "rot"
185
+ /* rot */
186
+ )}
187
+ .rotationsPerMinute=${this.rotationsPerMinute}
189
188
  >
190
189
  </obc-watch>
191
190
  <svg viewBox="${viewBox}">
@@ -205,10 +204,6 @@ let ObcCompass = class extends LitElement {
205
204
  /* cog */
206
205
  )
207
206
  )}
208
- <g id="rot">${rot(this.colorFor(
209
- "rot"
210
- /* rot */
211
- ))}</g>
212
207
  </svg>
213
208
  </div>
214
209
  `;
@@ -293,6 +288,18 @@ __decorateClass([
293
288
  __decorateClass([
294
289
  property({ type: Number })
295
290
  ], ObcCompass.prototype, "rotationsPerMinute", 2);
291
+ __decorateClass([
292
+ property({ type: String })
293
+ ], ObcCompass.prototype, "rotType", 2);
294
+ __decorateClass([
295
+ property({ type: String })
296
+ ], ObcCompass.prototype, "rotPosition", 2);
297
+ __decorateClass([
298
+ property({ type: Number })
299
+ ], ObcCompass.prototype, "rotMaxValue", 2);
300
+ __decorateClass([
301
+ property({ type: Number })
302
+ ], ObcCompass.prototype, "rotArcExtent", 2);
296
303
  __decorateClass([
297
304
  property({ type: String })
298
305
  ], ObcCompass.prototype, "direction", 2);
@@ -311,15 +318,13 @@ __decorateClass([
311
318
  __decorateClass([
312
319
  property({ type: Boolean })
313
320
  ], ObcCompass.prototype, "tickmarksInside", 2);
314
- __decorateClass([
315
- query("#rot")
316
- ], ObcCompass.prototype, "rot", 2);
317
321
  ObcCompass = __decorateClass([
318
322
  customElement("obc-compass")
319
323
  ], ObcCompass);
320
324
  export {
321
325
  CompassDirection,
322
326
  CompassPriorityElement,
323
- ObcCompass
327
+ ObcCompass,
328
+ RotType
324
329
  };
325
330
  //# sourceMappingURL=compass.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compass.js","sources":["../../../src/navigation-instruments/compass/compass.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html} from 'lit';\nimport {property, query} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {arrow, ArrowStyle} from './arrow.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {VesselImage, VesselImageSize, WatchCircleType} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {rot} from './rot.js';\nimport {RateOfTurnController} from '../rate-of-turn/rate-of-turn.controller.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum CompassPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n wind = 'wind',\n current = 'current',\n}\n\n/**\n * `<obc-compass>` – Full-featured compass with HDG/COG arrows, rate-of-turn indicator, and environmental overlays.\n *\n * Renders a circular compass instrument that displays heading (HDG) and\n * course-over-ground (COG) as rotating arrows over a triple-ring watch face.\n * It supports wind and current indicators, a vessel silhouette, heading\n * setpoint with auto at-setpoint detection, advice zones, and a rate-of-turn\n * (ROT) dot indicator. The compass can be oriented north-up, heading-up, or\n * course-up.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two styled arrows overlay the watch face,\n * rotating independently.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs;\n * triggered state is derived from whether the current heading falls\n * inside the advice range.\n * - **Rate of turn**: Animated ROT dot driven by `rotationsPerMinute`.\n * - **Environmental overlays**: Wind speed/direction and current\n * speed/direction indicators on the watch face.\n * - **Vessel image**: Configurable vessel silhouette centered on the\n * compass, rotating with heading.\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the\n * blue/enhanced color palette instead of the default gray/regular palette\n * (default: `Priority.regular`).\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values\n * in degrees.\n * - Use `direction` to control the compass orientation mode.\n * - Use `headingSetpoint` to show a target heading marker.\n * - Pass `headingAdvices` as an array of `AngleAdvice` objects for\n * caution/alert zones.\n * - Set `windSpeed` / `windFromDirection` and `currentSpeed` /\n * `currentFromDirection` to display environmental indicators.\n *\n * ## Example\n *\n * ```html\n * <obc-compass\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * priority=\"regular\"\n * vesselImage=\"genericTop\"\n * ></obc-compass>\n * ```\n *\n * @property {number} heading - The current heading of the vessel in degrees.\n * @property {number} courseOverGround - The current course over ground in degrees.\n * @property {number | null} headingSetpoint - The set point for the heading in degrees.\n * @property {boolean} atHeadingSetpoint - Indicates if the vessel is at the heading set point.\n * @property {boolean} autoAtHeadingSetpoint - Enables automatic at heading set point calculation.\n * @property {number} autoAtHeadingSetpointDeadband - The deadband for the heading set point in degrees.\n * @property {boolean} touching - Indicates if the compass is being touched.\n * @property {Array<AngleAdvice>} headingAdvices - An array of angle advices for the compass.\n * @property {number | null} windSpeed - The wind speed in beaufort scale number.\n * @property {number | null} windFromDirection - The direction the wind is coming from in degrees.\n * @property {number | null} currentSpeed - The current speed, number of arrows.\n * @property {number | null} currentFromDirection - The direction the current is coming from in degrees.\n * @property {VesselImage} vesselImage - The image of the vessel.\n * @property {number} rotationsPerMinute - The number of rotations per minute for the rate of turn controller.\n * @property {Priority} priority - Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette.\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n @property({type: Boolean}) animateSetpoint: boolean = false;\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: Number}) windSpeed: number | null = null;\n @property({type: Number}) windFromDirection: number | null = null;\n @property({type: Number}) currentSpeed: number | null = null;\n @property({type: Number}) currentFromDirection: number | null = null;\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassPriorityElement[] = [CompassPriorityElement.hdg];\n /** Show compass NSEW labels and north arrow. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n\n protected override updated(_changedProperties: PropertyValues): void {\n super.updated(_changedProperties);\n if (\n _changedProperties.has('rotationsPerMinute') &&\n this.rateOfTurnController\n ) {\n this.rateOfTurnController.rotationsPerMinute = this.rotationsPerMinute;\n }\n }\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this._headingSp.sync({\n setpoint: this.headingSetpoint ?? undefined,\n newSetpoint: this.newHeadingSetpoint,\n atSetpoint: this.atHeadingSetpoint,\n touching: this.touching,\n autoAtSetpoint: this.autoAtHeadingSetpoint,\n autoAtSetpointDeadband: this.autoAtHeadingSetpointDeadband,\n setpointAtZeroDeadband: this.headingSetpointAtZeroDeadband,\n setpointOverride: this.headingSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n @query('#rot')\n private rot!: HTMLElement;\n\n private rateOfTurnController?: RateOfTurnController;\n\n override firstUpdated() {\n this.rateOfTurnController = new RateOfTurnController(\n this,\n this.rot,\n this.rotationsPerMinute\n );\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n private getPadding() {\n const size = Math.min(this.clientHeight, this.clientWidth);\n const deltaWidth = 512 - size;\n const steps = deltaWidth / 128;\n let deltaPadding;\n if (deltaWidth > 0) {\n deltaPadding = steps * 48;\n } else {\n deltaPadding = steps * 6;\n }\n\n return 72 + deltaPadding;\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: CompassPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private colorFor(element: CompassPriorityElement): string | undefined {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const padding = this.getPadding();\n const width = (176 + padding) * 2;\n const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .padding=${padding}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .northArrow=${true}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .vessels=${[\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .wind=${this.windSpeed}\n .windFromDirectionDeg=${this.windFromDirection}\n .windColor=${this.colorFor(CompassPriorityElement.wind)}\n .current=${this.currentSpeed}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentColor=${this.colorFor(CompassPriorityElement.current)}\n .rotation=${this.getRotation()}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${arrow(\n ArrowStyle.HDG,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${arrow(\n ArrowStyle.COG,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n <g id=\"rot\">${rot(this.colorFor(CompassPriorityElement.rot))}</g>\n </svg>\n </div>\n `;\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass': ObcCompass;\n }\n}\n"],"names":["CompassDirection","CompassPriorityElement"],"mappings":"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"}
1
+ {"version":3,"file":"compass.js","sources":["../../../src/navigation-instruments/compass/compass.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {arrow, ArrowStyle} from './arrow.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum CompassPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n wind = 'wind',\n current = 'current',\n}\n\n/**\n * `<obc-compass>` – Full-featured compass with HDG/COG arrows, rate-of-turn indicator, and environmental overlays.\n *\n * Renders a circular compass instrument that displays heading (HDG) and\n * course-over-ground (COG) as rotating arrows over a triple-ring watch face.\n * It supports wind and current indicators, a vessel silhouette, heading\n * setpoint with auto at-setpoint detection, advice zones, and a rate-of-turn\n * (ROT) dot indicator. The compass can be oriented north-up, heading-up, or\n * course-up.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two styled arrows overlay the watch face,\n * rotating independently.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs;\n * triggered state is derived from whether the current heading falls\n * inside the advice range.\n * - **Rate of turn**: Animated ROT indicator driven by `rotationsPerMinute`.\n * Supports spinning dots (`rotType=\"dots\"`) and a banana-shaped arc bar\n * (`rotType=\"bar\"`) showing the HDG→COG span. Position on the outer\n * scale ring or inner circle via `rotPosition`.\n * - **Environmental overlays**: Wind speed/direction and current\n * speed/direction indicators on the watch face.\n * - **Vessel image**: Configurable vessel silhouette centered on the\n * compass, rotating with heading.\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the\n * blue/enhanced color palette instead of the default gray/regular palette\n * (default: `Priority.regular`).\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values\n * in degrees.\n * - Use `direction` to control the compass orientation mode.\n * - Use `headingSetpoint` to show a target heading marker.\n * - Pass `headingAdvices` as an array of `AngleAdvice` objects for\n * caution/alert zones.\n * - Set `windSpeed` / `windFromDirection` and `currentSpeed` /\n * `currentFromDirection` to display environmental indicators.\n *\n * ## Example\n *\n * ```html\n * <obc-compass\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * priority=\"regular\"\n * vesselImage=\"genericTop\"\n * ></obc-compass>\n * ```\n *\n * @property {number} heading - The current heading of the vessel in degrees.\n * @property {number} courseOverGround - The current course over ground in degrees.\n * @property {number | null} headingSetpoint - The set point for the heading in degrees.\n * @property {boolean} atHeadingSetpoint - Indicates if the vessel is at the heading set point.\n * @property {boolean} autoAtHeadingSetpoint - Enables automatic at heading set point calculation.\n * @property {number} autoAtHeadingSetpointDeadband - The deadband for the heading set point in degrees.\n * @property {boolean} touching - Indicates if the compass is being touched.\n * @property {Array<AngleAdvice>} headingAdvices - An array of angle advices for the compass.\n * @property {number | null} windSpeed - The wind speed in beaufort scale number.\n * @property {number | null} windFromDirection - The direction the wind is coming from in degrees.\n * @property {number | null} currentSpeed - The current speed, number of arrows.\n * @property {number | null} currentFromDirection - The direction the current is coming from in degrees.\n * @property {VesselImage} vesselImage - The image of the vessel.\n * @property {number} rotationsPerMinute - The number of rotations per minute for the rate of turn controller.\n * @property {RotType} rotType - ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (arc bar from HDG to COG).\n * @property {RotPosition} rotPosition - ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring).\n * @property {Priority} priority - Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette.\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n @property({type: Boolean}) animateSetpoint: boolean = false;\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: Number}) windSpeed: number | null = null;\n @property({type: Number}) windFromDirection: number | null = null;\n @property({type: Number}) currentSpeed: number | null = null;\n @property({type: Number}) currentFromDirection: number | null = null;\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: String}) rotType: RotType = RotType.dots;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotMaxValue: number = 10;\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassPriorityElement[] = [CompassPriorityElement.hdg];\n /** Show compass NSEW labels and north arrow. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this._headingSp.sync({\n setpoint: this.headingSetpoint ?? undefined,\n newSetpoint: this.newHeadingSetpoint,\n atSetpoint: this.atHeadingSetpoint,\n touching: this.touching,\n autoAtSetpoint: this.autoAtHeadingSetpoint,\n autoAtSetpointDeadband: this.autoAtHeadingSetpointDeadband,\n setpointAtZeroDeadband: this.headingSetpointAtZeroDeadband,\n setpointOverride: this.headingSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n private getPadding() {\n const size = Math.min(this.clientHeight, this.clientWidth);\n const deltaWidth = 512 - size;\n const steps = deltaWidth / 128;\n let deltaPadding;\n if (deltaWidth > 0) {\n deltaPadding = steps * 48;\n } else {\n deltaPadding = steps * 6;\n }\n\n return 72 + deltaPadding;\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: CompassPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private colorFor(element: CompassPriorityElement): string | undefined {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const padding = this.getPadding();\n const width = (176 + padding) * 2;\n const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .padding=${padding}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .northArrow=${true}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .vessels=${[\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .wind=${this.windSpeed}\n .windFromDirectionDeg=${this.windFromDirection}\n .windColor=${this.colorFor(CompassPriorityElement.wind)}\n .current=${this.currentSpeed}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentColor=${this.colorFor(CompassPriorityElement.current)}\n .rotation=${this.getRotation()}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading + (this.getRotation() ?? 0)}\n .rotEndAngle=${this.heading +\n (this.rotationsPerMinute / (this.rotMaxValue || 1)) *\n this.rotArcExtent +\n (this.getRotation() ?? 0)}\n .rotPriority=${this.priorityFor(CompassPriorityElement.rot)}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${arrow(\n ArrowStyle.HDG,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${arrow(\n ArrowStyle.COG,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n </svg>\n </div>\n `;\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass': ObcCompass;\n }\n}\n"],"names":["CompassDirection","CompassPriorityElement"],"mappings":"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"}