@oicl/openbridge-webcomponents 0.0.20260409094807 → 0.0.20260410061657

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 (25) hide show
  1. package/dist/navigation-instruments/compass/compass.d.ts +1 -0
  2. package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
  3. package/dist/navigation-instruments/compass/compass.js +6 -1
  4. package/dist/navigation-instruments/compass/compass.js.map +1 -1
  5. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts +1 -0
  6. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts.map +1 -1
  7. package/dist/navigation-instruments/compass-flat/compass-flat.js +6 -1
  8. package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
  9. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts +1 -0
  10. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
  11. package/dist/navigation-instruments/compass-sector/compass-sector.js +7 -2
  12. package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
  13. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts +1 -0
  14. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts.map +1 -1
  15. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js +6 -1
  16. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js.map +1 -1
  17. package/dist/navigation-instruments/watch/watch.d.ts +1 -0
  18. package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
  19. package/dist/navigation-instruments/watch/watch.js +7 -5
  20. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  21. package/dist/navigation-instruments/watch-flat/watch-flat.d.ts +1 -0
  22. package/dist/navigation-instruments/watch-flat/watch-flat.d.ts.map +1 -1
  23. package/dist/navigation-instruments/watch-flat/watch-flat.js +7 -5
  24. package/dist/navigation-instruments/watch-flat/watch-flat.js.map +1 -1
  25. package/package.json +1 -1
@@ -119,6 +119,7 @@ export declare class ObcCompass extends LitElement {
119
119
  rotMaxValue: number;
120
120
  rotArcExtent: number;
121
121
  rotPortStarboard: boolean;
122
+ rotAtZeroDeadband: number;
122
123
  direction: CompassDirection;
123
124
  state: InstrumentState;
124
125
  priority: Priority;
@@ -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,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;IACzB,gBAAgB,EAAE,OAAO,CAAS;IACnC,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;IA0Ef,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;AAI3B,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;IACzB,gBAAgB,EAAE,OAAO,CAAS;IACnC,iBAAiB,EAAE,MAAM,CAAyB;IAClD,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;IA2Ef,OAAgB,MAAM,0BAwBpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
@@ -6,10 +6,10 @@ 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 { RotType, RotPosition, ROT_ZERO_DEADBAND_DEG } from "../rate-of-turn/rot-renderer.js";
9
10
  import { customElement } from "../../decorator.js";
10
11
  import { InstrumentState, Priority } from "../types.js";
11
12
  import { VesselImage, VesselImageSize } from "../watch/vessel.js";
12
- import { RotType, RotPosition } from "../rate-of-turn/rot-renderer.js";
13
13
  var __defProp = Object.defineProperty;
14
14
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
15
  var __decorateClass = (decorators, target, key, kind) => {
@@ -59,6 +59,7 @@ let ObcCompass = class extends LitElement {
59
59
  this.rotMaxValue = 10;
60
60
  this.rotArcExtent = 60;
61
61
  this.rotPortStarboard = false;
62
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_DEG;
62
63
  this.direction = "northUp";
63
64
  this.state = InstrumentState.active;
64
65
  this.priority = Priority.regular;
@@ -186,6 +187,7 @@ let ObcCompass = class extends LitElement {
186
187
  /* rot */
187
188
  )}
188
189
  .rotPortStarboard=${this.rotPortStarboard}
190
+ .rotAtZeroDeadband=${this.rotAtZeroDeadband}
189
191
  .rotationsPerMinute=${this.rotationsPerMinute}
190
192
  >
191
193
  </obc-watch>
@@ -305,6 +307,9 @@ __decorateClass([
305
307
  __decorateClass([
306
308
  property({ type: Boolean })
307
309
  ], ObcCompass.prototype, "rotPortStarboard", 2);
310
+ __decorateClass([
311
+ property({ type: Number })
312
+ ], ObcCompass.prototype, "rotAtZeroDeadband", 2);
308
313
  __decorateClass([
309
314
  property({ type: String })
310
315
  ], ObcCompass.prototype, "direction", 2);
@@ -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} 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: Boolean}) rotPortStarboard: boolean = false;\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 .rotPortStarboard=${this.rotPortStarboard}\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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"}
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 {ROT_ZERO_DEADBAND_DEG} from '../rate-of-turn/rot-renderer.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: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\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 .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband}\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":";;;;;;;;;;;;;;;;;;;;;;AAoBO,IAAK,qCAAAA,sBAAL;AACLA,oBAAA,SAAA,IAAU;AACVA,oBAAA,WAAA,IAAY;AACZA,oBAAA,UAAA,IAAW;AAHD,SAAAA;AAAA,GAAA,oBAAA,CAAA,CAAA;AAML,IAAK,2CAAAC,4BAAL;AACLA,0BAAA,KAAA,IAAM;AACNA,0BAAA,KAAA,IAAM;AACNA,0BAAA,KAAA,IAAM;AACNA,0BAAA,MAAA,IAAO;AACPA,0BAAA,SAAA,IAAU;AALA,SAAAA;AAAA,GAAA,0BAAA,CAAA,CAAA;AAwFL,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,UAAU;AACV,SAAA,mBAAmB;AAEnB,SAAA,kBAAiC;AAEhC,SAAA,oBAA6B;AAC9B,SAAA,gCAAwC;AACvC,SAAA,0BAAmC;AACjB,SAAA,wBAC3C;AACwB,SAAA,gCAAwC;AACvC,SAAA,kBAA2B;AAC3B,SAAA,WAAoB;AACJ,SAAA,iBAAgC,CAAA;AACjD,SAAA,YAA2B;AAC3B,SAAA,oBAAmC;AACnC,SAAA,eAA8B;AAC9B,SAAA,uBAAsC;AACtC,SAAA,cAA2B,YAAY;AACvC,SAAA,qBAA6B;AAC7B,SAAA,UAAmB,QAAQ;AAC3B,SAAA,cAA2B,YAAY;AACvC,SAAA,cAAsB;AACtB,SAAA,eAAuB;AACtB,SAAA,mBAA4B;AAC7B,SAAA,oBAA4B;AAC5B,SAAA,YACxB;AACwB,SAAA,QAAyB,gBAAgB;AACzC,SAAA,WAAqB,SAAS;AAExD,SAAA,mBAA6C;AAAA,MAAC;AAAA;AAAA,IAAA;AAEnB,SAAA,aAAsB;AAEtB,SAAA,kBAA2B;AAEtD,SAAQ,aAAa,IAAI,eAAe;AAAA,MACtC,mBAAmB;AAAA,MACnB,gBAAgB,MAAM,KAAK,cAAA;AAAA,IAAc,CAC1C;AAwBD,SAAQ,oBAAoB,IAAI,iBAAiB,MAAM,CAAA,CAAE;AAAA,EAAA;AAAA,EAtBhD,WAAW,SAA+B;AACjD,UAAM,WAAW,OAAO;AACxB,SAAK,WAAW,KAAK;AAAA,MACnB,UAAU,KAAK,mBAAmB;AAAA,MAClC,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,wBAAwB,KAAK;AAAA,MAC7B,wBAAwB,KAAK;AAAA,MAC7B,kBAAkB,KAAK;AAAA,MACvB,iBAAiB,KAAK;AAAA,IAAA,CACvB;AAAA,EACH;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA;AACN,SAAK,WAAW,QAAA;AAAA,EAClB;AAAA,EAMQ,aAAa;AACnB,UAAM,OAAO,KAAK,IAAI,KAAK,cAAc,KAAK,WAAW;AACzD,UAAM,aAAa,MAAM;AACzB,UAAM,QAAQ,aAAa;AAC3B,QAAI;AACJ,QAAI,aAAa,GAAG;AAClB,qBAAe,QAAQ;AAAA,IACzB,OAAO;AACL,qBAAe,QAAQ;AAAA,IACzB;AAEA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,iBAAmC;AAC7C,WAAO,KAAK,eAAe,IAAI,CAAC,EAAC,UAAU,UAAU,QAAQ,WAAU;AACrE,YAAM,QACJ,KAAK,WAAW,YAAY,KAAK,WAAW,WACxC,YAAY,YACZ,SACE,YAAY,SACZ,YAAY;AACpB,aAAO,EAAC,UAAU,UAAU,MAAM,MAAA;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,SAA2C;AAC7D,UAAM,WAAW,MAAM,QAAQ,KAAK,gBAAgB,IAChD,KAAK,mBACL,CAAA;AACJ,WAAO,SAAS,SAAS,OAAO,IAAI,KAAK,WAAW,SAAS;AAAA,EAC/D;AAAA,EAEQ,SAAS,SAAqD;AACpE,WAAO,KAAK,YAAY,OAAO,MAAM,SAAS,WAC1C,+CACA;AAAA,EACN;AAAA,EAEQ,cAAkC;AACxC,QAAI,KAAK,cAAc,WAA0B;AAC/C,aAAO;AAAA,IACT,WAAW,KAAK,cAAc,aAA4B;AACxD,aAAO,CAAC,KAAK;AAAA,IACf,WAAW,KAAK,cAAc,YAA2B;AACvD,aAAO,CAAC,KAAK;AAAA,IACf;AACA,WAAO;AAAA,EACT;AAAA,EAES,SAAS;AAChB,UAAM,YAAwB;AAAA,MAC5B,EAAC,OAAO,GAAG,MAAM,aAAa,KAAA;AAAA,MAC9B,EAAC,OAAO,IAAI,MAAM,aAAa,KAAA;AAAA,MAC/B,EAAC,OAAO,KAAK,MAAM,aAAa,KAAA;AAAA,MAChC,EAAC,OAAO,KAAK,MAAM,aAAa,KAAA;AAAA,IAAI;AAGtC,UAAM,UAAU,KAAK,WAAA;AACrB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,UAAU,IAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,IAAI,KAAK,IAAI,KAAK;AAE7D,WAAO;AAAA;AAAA;AAAA,sBAGW,KAAK,QAAQ;AAAA,qBACd,OAAO;AAAA,qBACP,KAAK,cAAc;AAAA,uBACjB,SAAS;AAAA,mBACb,KAAK,KAAK;AAAA,6BACA,gBAAgB,MAAM;AAAA,wBAC3B,KAAK,UAAU;AAAA,6BACV,KAAK,eAAe;AAAA,8BACnB,IAAI;AAAA,wBACV,IAAI;AAAA,2BACD,KAAK,mBAAmB,MAAS;AAAA,8BAC9B,KAAK,kBAAkB;AAAA,6BACxB,KAAK,WAAW,kBAAkB,KAAK,OAAO,CAAC;AAAA,yCACnC,KAAK,6BAA6B;AAAA,8BAC7C,KAAK,uBAAuB;AAAA,sBACpC,KAAK,QAAQ;AAAA,6BACN,KAAK,eAAe;AAAA,qBAC5B;AAAA,MACT;AAAA,QACE,MAAM,gBAAgB;AAAA,QACtB,aAAa,KAAK;AAAA,QAClB,WAAW,UAAU,KAAK,OAAO;AAAA,MAAA;AAAA,IACnC,CACD;AAAA,kBACO,KAAK,SAAS;AAAA,kCACE,KAAK,iBAAiB;AAAA,uBACjC,KAAK;AAAA,MAAS;AAAA;AAAA,IAAA,CAA4B;AAAA,qBAC5C,KAAK,YAAY;AAAA,qCACD,KAAK,oBAAoB;AAAA,0BACpC,KAAK;AAAA,MAAS;AAAA;AAAA,IAAA,CAA+B;AAAA,sBACjD,KAAK,aAAa;AAAA,qBACnB,KAAK,OAAO;AAAA,yBACR,KAAK,WAAW;AAAA,2BACd,KAAK,WAAW,KAAK,YAAA,KAAiB,EAAE;AAAA,yBAC1C,KAAK,UACnB,KAAK,sBAAsB,KAAK,eAAe,KAC9C,KAAK,gBACN,KAAK,YAAA,KAAiB,EAAE;AAAA,yBACV,KAAK;AAAA,MAAY;AAAA;AAAA,IAAA,CAA2B;AAAA,8BACvC,KAAK,gBAAgB;AAAA,+BACpB,KAAK,iBAAiB;AAAA,gCACrB,KAAK,kBAAkB;AAAA;AAAA;AAAA,wBAG/B,OAAO;AAAA,YACnB;AAAA,MACA,WAAW;AAAA,MACX,KAAK,WAAW,KAAK,YAAA,KAAiB;AAAA,MACtC,KAAK;AAAA,QAAY;AAAA;AAAA,MAAA;AAAA,IAA0B,CAC5C;AAAA,YACC;AAAA,MACA,WAAW;AAAA,MACX,KAAK,oBAAoB,KAAK,YAAA,KAAiB;AAAA,MAC/C,KAAK;AAAA,QAAY;AAAA;AAAA,MAAA;AAAA,IAA0B,CAC5C;AAAA;AAAA;AAAA;AAAA,EAIT;AA2BF;AAzNa,WAgMK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA/LC,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,WACe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,WAEe,WAAA,oBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,WAIe,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,WAKe,WAAA,sBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,WAMgB,WAAA,qBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,WAOe,WAAA,iCAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GARd,WAQgB,WAAA,2BAAA,CAAA;AACkB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAThC,WASkC,WAAA,yBAAA,CAAA;AAEnB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAXb,WAWe,WAAA,iCAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAZd,WAYgB,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAbd,WAagB,WAAA,YAAA,CAAA;AACgB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAd9B,WAcgC,WAAA,kBAAA,CAAA;AACjB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAfb,WAee,WAAA,aAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhBb,WAgBe,WAAA,qBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjBb,WAiBe,WAAA,gBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlBb,WAkBe,WAAA,wBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnBb,WAmBe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApBb,WAoBe,WAAA,sBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArBb,WAqBe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtBb,WAsBe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvBb,WAuBe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAxBb,WAwBe,WAAA,gBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAzBd,WAyBgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA1Bb,WA0Be,WAAA,qBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Bb,WA2Be,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Bb,WA6Be,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Bb,WA8Be,WAAA,YAAA,CAAA;AAE1B,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GA/B9B,WAgCX,WAAA,oBAAA,CAAA;AAE2B,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAlCd,WAkCgB,WAAA,cAAA,CAAA;AAEA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GApCd,WAoCgB,WAAA,mBAAA,CAAA;AApChB,aAAN,gBAAA;AAAA,EADN,cAAc,aAAa;AAAA,GACf,UAAA;"}
@@ -69,6 +69,7 @@ export declare class ObcCompassFlat extends LitElement {
69
69
  rotMaxValue: number;
70
70
  rotArcExtent: number;
71
71
  rotPortStarboard: boolean;
72
+ rotAtZeroDeadband: number;
72
73
  private containerWidth;
73
74
  private maxContainerWidth;
74
75
  private resizeObserver;
@@ -1 +1 @@
1
- {"version":3,"file":"compass-flat.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass-flat/compass-flat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0C,MAAM,KAAK,CAAC;AAIxE,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,OAAO,EAER,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAC,OAAO,EAAC,CAAC;AAEjB,oBAAY,0BAA0B;IACpC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AAED,oBAAY,aAAa;IACvB,GAAG,MAAM;IACT,MAAM,KAAK;CACZ;AAED,oBAAY,UAAU;IACpB,OAAO,gDAAgD;CACxD;AAED,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,aAAa,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBACa,cAAe,SAAQ,UAAU;IACjB,YAAY,EAAE,OAAO,CAAS;IAC/B,OAAO,SAAK;IACZ,gBAAgB,SAAK;IACrB,YAAY,SAAK;IACjB,GAAG,SAAM;IACT,MAAM,SAAM;IACZ,MAAM,SAAO;IACb,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,0BAA0B,EAAE,CAE5C;IACwB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAK;IAC/B,WAAW,EAAE,MAAM,CAAM;IACzB,YAAY,EAAE,MAAM,CAAM;IACzB,gBAAgB,EAAE,OAAO,CAAS;IAEpD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,iBAAiB,CAAK;IAEvC,OAAO,CAAC,cAAc,CASnB;IAEM,iBAAiB;IAKjB,oBAAoB;IAK7B,cAAc;;;;;IAsCd,OAAO,CAAC,yBAAyB;IAiCjC,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,aAAa;IAMrB,OAAO,KAAK,MAAM,GAIjB;IAED,OAAO,CAAC,MAAM;IAQL,MAAM;IAsDf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
1
+ {"version":3,"file":"compass-flat.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass-flat/compass-flat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0C,MAAM,KAAK,CAAC;AAIxE,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,OAAO,EAGR,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAC,OAAO,EAAC,CAAC;AAEjB,oBAAY,0BAA0B;IACpC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AAED,oBAAY,aAAa;IACvB,GAAG,MAAM;IACT,MAAM,KAAK;CACZ;AAED,oBAAY,UAAU;IACpB,OAAO,gDAAgD;CACxD;AAED,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,aAAa,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBACa,cAAe,SAAQ,UAAU;IACjB,YAAY,EAAE,OAAO,CAAS;IAC/B,OAAO,SAAK;IACZ,gBAAgB,SAAK;IACrB,YAAY,SAAK;IACjB,GAAG,SAAM;IACT,MAAM,SAAM;IACZ,MAAM,SAAO;IACb,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,0BAA0B,EAAE,CAE5C;IACwB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAK;IAC/B,WAAW,EAAE,MAAM,CAAM;IACzB,YAAY,EAAE,MAAM,CAAM;IACzB,gBAAgB,EAAE,OAAO,CAAS;IACnC,iBAAiB,EAAE,MAAM,CAAyB;IAEnE,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,iBAAiB,CAAK;IAEvC,OAAO,CAAC,cAAc,CASnB;IAEM,iBAAiB;IAKjB,oBAAoB;IAK7B,cAAc;;;;;IAsCd,OAAO,CAAC,yBAAyB;IAiCjC,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,aAAa;IAMrB,OAAO,KAAK,MAAM,GAIjB;IAED,OAAO,CAAC,MAAM;IAQL,MAAM;IAuDf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
@@ -5,7 +5,7 @@ import { TickmarkType } from "../watch-flat/tickmark-flat.js";
5
5
  import "../watch-flat/watch-flat.js";
6
6
  import { customElement } from "../../decorator.js";
7
7
  import { Priority } from "../types.js";
8
- import { LINEAR_DOT_ANGLE_SPACING } from "../rate-of-turn/rot-renderer.js";
8
+ import { ROT_ZERO_DEADBAND_DEG, LINEAR_DOT_ANGLE_SPACING } from "../rate-of-turn/rot-renderer.js";
9
9
  import { RotType } from "../rate-of-turn/rot-renderer.js";
10
10
  var __defProp = Object.defineProperty;
11
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -51,6 +51,7 @@ let ObcCompassFlat = class extends LitElement {
51
51
  this.rotMaxValue = 10;
52
52
  this.rotArcExtent = 60;
53
53
  this.rotPortStarboard = false;
54
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_DEG;
54
55
  this.containerWidth = 0;
55
56
  this.maxContainerWidth = 0;
56
57
  this.resizeObserver = new ResizeObserver((entries) => {
@@ -230,6 +231,7 @@ let ObcCompassFlat = class extends LitElement {
230
231
  /* rot */
231
232
  )}
232
233
  .rotPortStarboard=${this.rotPortStarboard}
234
+ .rotAtZeroDeadband=${this.rotAtZeroDeadband * translationScale}
233
235
  ></obc-watch-flat>
234
236
  <svg viewBox=${viewBox} xmlns="http://www.w3.org/2000/svg">
235
237
  ${this.HDGSvg}${this.COGSvg(translation)}
@@ -281,6 +283,9 @@ __decorateClass([
281
283
  __decorateClass([
282
284
  property({ type: Boolean })
283
285
  ], ObcCompassFlat.prototype, "rotPortStarboard", 2);
286
+ __decorateClass([
287
+ property({ type: Number })
288
+ ], ObcCompassFlat.prototype, "rotAtZeroDeadband", 2);
284
289
  __decorateClass([
285
290
  state()
286
291
  ], ObcCompassFlat.prototype, "containerWidth", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"compass-flat.js","sources":["../../../src/navigation-instruments/compass-flat/compass-flat.ts"],"sourcesContent":["import {LitElement, html, svg, SVGTemplateResult, unsafeCSS} from 'lit';\nimport componentStyle from './compass-flat.css?inline';\nimport {property, state} from 'lit/decorators.js';\nimport {Tickmark, TickmarkType} from '../watch-flat/tickmark-flat.js';\nimport '../watch-flat/watch-flat.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\nimport {\n RotType,\n LINEAR_DOT_ANGLE_SPACING,\n} from '../rate-of-turn/rot-renderer.js';\n\nexport {RotType};\n\nexport enum CompassFlatPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n}\n\nexport enum LabelPosition {\n top = -45,\n bottom = 50,\n}\n\nexport enum LabelStyle {\n regular = 'var(--instrument-tick-mark-secondary-color)',\n}\n\nexport interface Label {\n x: number;\n y: LabelPosition;\n text: string;\n}\n\n/**\n * `<obc-compass-flat>` — Horizontal strip compass with HDG/COG arrows and optional rate-of-turn indicator.\n *\n * Renders a flat (non-circular) compass strip that scrolls horizontally to\n * display the current heading. A filled HDG arrow sits at the center while a\n * hollow COG arrow is positioned at the angular difference. The strip\n * auto-scales its field of view so both arrows remain visible. Cardinal\n * labels (N, S, E, W) and tickmarks are generated at densities responsive to\n * the strip width.\n *\n * ## Features\n *\n * - **Auto-scaling FOV**: The visible compass range widens to keep both HDG\n * and COG arrows in view, bounded by `minFOV` / `maxFOV`.\n * - **HDG / COG arrows**: Filled (HDG) and hollow (COG) arrow SVGs positioned\n * along the strip.\n * - **FOV indicator**: Optional numeric labels showing the port/starboard\n * bearing range and current heading.\n * - **Rate of turn**: Animated linear ROT indicator (spinning dots or\n * horizontal bar) via `rotType`. When enabled, a bottom bar is added to\n * the strip to house the indicator.\n * - **Color priority**: Per-element priority for HDG, COG, and ROT via\n * `priorityElements`.\n *\n * @property {number} heading - Current heading in degrees.\n * @property {number} courseOverGround - Current COG in degrees.\n * @property {RotType|undefined} rotType - ROT display mode: `'dots'`, `'bar'`, or `undefined` (hidden).\n * @property {number} rotationsPerMinute - ROT spin speed; sign controls direction.\n * @property {number} rotMaxValue - Maximum ROT value for bar-extent mapping.\n * @property {number} rotArcExtent - Degrees of bar arc per max-value ROT (default 60).\n *\n * @ignition-base-height: 170px\n * @ignition-base-width: 512px\n */\n@customElement('obc-compass-flat')\nexport class ObcCompassFlat extends LitElement {\n @property({type: Boolean}) FOVIndicator: boolean = false;\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n @property({type: Number}) tickInterval = 5;\n @property({type: Number}) FOV = 45;\n @property({type: Number}) minFOV = 45;\n @property({type: Number}) maxFOV = 180;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassFlatPriorityElement[] = [\n CompassFlatPriorityElement.hdg,\n ];\n @property({type: String}) rotType: RotType | undefined;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: Number}) rotMaxValue: number = 10;\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n\n @state() private containerWidth = 0;\n @state() private maxContainerWidth = 0;\n\n private resizeObserver: ResizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n // Made by chatGPT so that the text is inside the wrapper\n this.maxContainerWidth = -125.36 + 3.79 * entry.contentRect.height;\n this.containerWidth = Math.min(\n entry.contentRect.width,\n this.maxContainerWidth\n );\n }\n });\n\n override connectedCallback() {\n super.connectedCallback();\n this.resizeObserver.observe(this);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.resizeObserver.unobserve(this);\n }\n\n generateLabels() {\n if (this.containerWidth < 192) {\n return [];\n } else if (this.containerWidth <= 300) {\n return [\n {x: -180, y: LabelPosition.top, text: 'S'},\n {x: -90, y: LabelPosition.top, text: 'W'},\n {x: 0, y: LabelPosition.top, text: 'N'},\n {x: 90, y: LabelPosition.top, text: 'E'},\n {x: 180, y: LabelPosition.top, text: 'S'},\n {x: 270, y: LabelPosition.top, text: 'W'},\n {x: 360, y: LabelPosition.top, text: 'N'},\n {x: 450, y: LabelPosition.top, text: 'E'},\n {x: 540, y: LabelPosition.top, text: 'S'},\n ];\n } else {\n return [\n {x: -180, y: LabelPosition.top, text: 'S'},\n {x: -135, y: LabelPosition.top, text: 'SW'},\n {x: -90, y: LabelPosition.top, text: 'W'},\n {x: -45, y: LabelPosition.top, text: 'NW'},\n {x: 0, y: LabelPosition.top, text: 'N'},\n {x: 45, y: LabelPosition.top, text: 'NE'},\n {x: 90, y: LabelPosition.top, text: 'E'},\n {x: 135, y: LabelPosition.top, text: 'SE'},\n {x: 180, y: LabelPosition.top, text: 'S'},\n {x: 225, y: LabelPosition.top, text: 'SW'},\n {x: 270, y: LabelPosition.top, text: 'W'},\n {x: 315, y: LabelPosition.top, text: 'NW'},\n {x: 360, y: LabelPosition.top, text: 'N'},\n {x: 405, y: LabelPosition.top, text: 'NE'},\n {x: 450, y: LabelPosition.top, text: 'E'},\n {x: 495, y: LabelPosition.top, text: 'SE'},\n {x: 540, y: LabelPosition.top, text: 'S'},\n ];\n }\n }\n\n private generateIntervalTickmarks(scale: number): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n let cardinalInterval = 90;\n\n if (this.containerWidth > 300) {\n cardinalInterval = 45;\n } else if (this.containerWidth < 192) {\n cardinalInterval = 0;\n }\n\n // Guard against zero/negative/non-finite interval to prevent infinite loops\n if (\n !this.tickInterval ||\n this.tickInterval <= 0 ||\n !Number.isFinite(this.tickInterval)\n ) {\n return tickmarks;\n }\n\n for (\n let angle = -180;\n angle < this.maxFOV * 3;\n angle += this.tickInterval\n ) {\n if (cardinalInterval !== 0 && angle % cardinalInterval === 0) {\n continue;\n }\n tickmarks.push({angle: angle * scale, type: TickmarkType.secondary});\n }\n\n return tickmarks;\n }\n\n private generateCardinalTickmarks(\n scale: number,\n labels: Label[]\n ): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n\n for (const label of labels) {\n tickmarks.push({angle: label.x * scale, type: TickmarkType.main});\n }\n\n return tickmarks;\n }\n\n private generateTickmarks(scale: number, labels: Label[]): Tickmark[] {\n return [\n ...this.generateCardinalTickmarks(scale, labels),\n ...this.generateIntervalTickmarks(scale),\n ];\n }\n\n private renderFOVIndicator(): SVGTemplateResult[] {\n const indicators: SVGTemplateResult[] = [];\n\n const maxAdjustment = 10;\n const minContainerWidth = 300;\n const maxContainerWidth = 512;\n\n let yAdjustment = 0;\n if (this.containerWidth < maxContainerWidth) {\n const widthRange = maxContainerWidth - minContainerWidth;\n const scaleFactor =\n (maxContainerWidth - this.containerWidth) / widthRange;\n yAdjustment = scaleFactor * maxAdjustment;\n }\n\n const y = LabelPosition.bottom + yAdjustment + (this.rotType ? 12 : 0);\n\n indicators.push(svg`\n <text x=\"-175\" y=${y} class=\"label left\" fill=${LabelStyle.regular}>\n ${-this.FOV}\\u00B0\n </text>`);\n\n indicators.push(svg`\n <text x=\"0\" y=${y} class=\"label\" fill=${LabelStyle.regular}>\n ${this.heading}\\u00B0\n </text>`);\n\n indicators.push(svg`\n <text x=\"175\" y=${y} class=\"label right\" fill=${LabelStyle.regular}>\n ${this.FOV}\\u00B0\n </text>`);\n\n return indicators;\n }\n\n private priorityFor(element: CompassFlatPriorityElement): 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 arrowColorFor(element: CompassFlatPriorityElement): string {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n }\n\n private get HDGSvg(): SVGTemplateResult {\n return svg`<g transform=\"translate(-24, -74)\">\n <path d=\"M36.7011 44.1445L36.6898 44.1379L36.6781 44.1318L24.2301 37.6823L24.0001 37.5631L23.7701 37.6823L11.3221 44.1318L11.3104 44.1379L11.2991 44.1445C9.25497 45.3438 6.78661 43.308 7.68828 41.0919L22.6036 4.43285C23.1096 3.18905 24.8906 3.18905 25.3967 4.43284L40.3119 41.0919C41.2136 43.308 38.7452 45.3438 36.7011 44.1445Z\" fill=\"${this.arrowColorFor(CompassFlatPriorityElement.hdg)}\" stroke=\"var(--border-silhouette-color)\"/>\n </g>`;\n }\n\n private COGSvg(translation: number): SVGTemplateResult {\n return svg`\n <g transform=\"translate(${-24 + translation}, -74)\">\n <path d=\"M31.9025 36.0262L33.1068 36.6502L32.5956 35.3938L24.4632 15.406L24.0001 14.2677L23.537 15.406L15.4046 35.3938L14.8935 36.6502L16.0978 36.0262L24.0001 31.9319L31.9025 36.0262ZM36.7011 44.1445L36.6898 44.1379L36.6781 44.1318L24.2301 37.6823L24.0001 37.5631L23.7701 37.6823L11.3221 44.1318L11.3104 44.1379L11.2991 44.1445C9.25497 45.3438 6.78661 43.308 7.68828 41.0919L22.6036 4.43285C23.1096 3.18905 24.8906 3.18905 25.3967 4.43284L40.3119 41.0919C41.2136 43.308 38.7452 45.3438 36.7011 44.1445Z\" fill=\"${this.arrowColorFor(CompassFlatPriorityElement.cog)}\" stroke=\"var(--border-silhouette-color)\"/>\n </g>\n `;\n }\n\n override render() {\n let angleDiff = this.courseOverGround - this.heading;\n\n if (angleDiff > this.maxFOV) {\n angleDiff -= 360;\n } else if (angleDiff < -this.maxFOV) {\n angleDiff += 360;\n }\n\n this.FOV = Math.max(this.minFOV, Math.abs(angleDiff));\n\n const baseOffset = 5;\n const translationScale = (baseOffset * 35) / this.FOV;\n\n const translation = angleDiff * translationScale;\n const labels = this.generateLabels();\n const tickmarks = this.generateTickmarks(translationScale, labels);\n const scaledLabels = labels.map((l) => ({\n ...l,\n x: l.x * translationScale,\n }));\n\n const hasBottomBar = !!this.rotType;\n const arrowViewBoxY = hasBottomBar\n ? -128 + Math.round((12 * 384) / 352)\n : -128;\n const viewBox = `-192 ${arrowViewBoxY} 384 128`;\n\n return html`\n <div class=\"container\" style=\"max-width:${this.maxContainerWidth}px\">\n <obc-watch-flat\n .FOVIndicator=${this.FOVIndicator ? this.renderFOVIndicator() : []}\n .labels=${scaledLabels}\n .rotation=${this.heading}\n .tickmarks=${tickmarks}\n .tickmarkSpacing=${translationScale}\n .bottomBar=${!!this.rotType}\n .rotType=${this.rotType}\n .rotStartX=${0}\n .rotEndX=${(this.rotationsPerMinute / (this.rotMaxValue || 1)) *\n this.rotArcExtent *\n translationScale}\n .rotDotSpacing=${LINEAR_DOT_ANGLE_SPACING * translationScale}\n .rotationsPerMinute=${this.rotationsPerMinute}\n .rotPriority=${this.priorityFor(CompassFlatPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n ></obc-watch-flat>\n <svg viewBox=${viewBox} xmlns=\"http://www.w3.org/2000/svg\">\n ${this.HDGSvg}${this.COGSvg(translation)}\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass-flat': ObcCompassFlat;\n }\n}\n"],"names":["CompassFlatPriorityElement","LabelPosition","LabelStyle"],"mappings":"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"}
1
+ {"version":3,"file":"compass-flat.js","sources":["../../../src/navigation-instruments/compass-flat/compass-flat.ts"],"sourcesContent":["import {LitElement, html, svg, SVGTemplateResult, unsafeCSS} from 'lit';\nimport componentStyle from './compass-flat.css?inline';\nimport {property, state} from 'lit/decorators.js';\nimport {Tickmark, TickmarkType} from '../watch-flat/tickmark-flat.js';\nimport '../watch-flat/watch-flat.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\nimport {\n RotType,\n LINEAR_DOT_ANGLE_SPACING,\n ROT_ZERO_DEADBAND_DEG,\n} from '../rate-of-turn/rot-renderer.js';\n\nexport {RotType};\n\nexport enum CompassFlatPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n}\n\nexport enum LabelPosition {\n top = -45,\n bottom = 50,\n}\n\nexport enum LabelStyle {\n regular = 'var(--instrument-tick-mark-secondary-color)',\n}\n\nexport interface Label {\n x: number;\n y: LabelPosition;\n text: string;\n}\n\n/**\n * `<obc-compass-flat>` — Horizontal strip compass with HDG/COG arrows and optional rate-of-turn indicator.\n *\n * Renders a flat (non-circular) compass strip that scrolls horizontally to\n * display the current heading. A filled HDG arrow sits at the center while a\n * hollow COG arrow is positioned at the angular difference. The strip\n * auto-scales its field of view so both arrows remain visible. Cardinal\n * labels (N, S, E, W) and tickmarks are generated at densities responsive to\n * the strip width.\n *\n * ## Features\n *\n * - **Auto-scaling FOV**: The visible compass range widens to keep both HDG\n * and COG arrows in view, bounded by `minFOV` / `maxFOV`.\n * - **HDG / COG arrows**: Filled (HDG) and hollow (COG) arrow SVGs positioned\n * along the strip.\n * - **FOV indicator**: Optional numeric labels showing the port/starboard\n * bearing range and current heading.\n * - **Rate of turn**: Animated linear ROT indicator (spinning dots or\n * horizontal bar) via `rotType`. When enabled, a bottom bar is added to\n * the strip to house the indicator.\n * - **Color priority**: Per-element priority for HDG, COG, and ROT via\n * `priorityElements`.\n *\n * @property {number} heading - Current heading in degrees.\n * @property {number} courseOverGround - Current COG in degrees.\n * @property {RotType|undefined} rotType - ROT display mode: `'dots'`, `'bar'`, or `undefined` (hidden).\n * @property {number} rotationsPerMinute - ROT spin speed; sign controls direction.\n * @property {number} rotMaxValue - Maximum ROT value for bar-extent mapping.\n * @property {number} rotArcExtent - Degrees of bar arc per max-value ROT (default 60).\n *\n * @ignition-base-height: 170px\n * @ignition-base-width: 512px\n */\n@customElement('obc-compass-flat')\nexport class ObcCompassFlat extends LitElement {\n @property({type: Boolean}) FOVIndicator: boolean = false;\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n @property({type: Number}) tickInterval = 5;\n @property({type: Number}) FOV = 45;\n @property({type: Number}) minFOV = 45;\n @property({type: Number}) maxFOV = 180;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassFlatPriorityElement[] = [\n CompassFlatPriorityElement.hdg,\n ];\n @property({type: String}) rotType: RotType | undefined;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: Number}) rotMaxValue: number = 10;\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\n\n @state() private containerWidth = 0;\n @state() private maxContainerWidth = 0;\n\n private resizeObserver: ResizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n // Made by chatGPT so that the text is inside the wrapper\n this.maxContainerWidth = -125.36 + 3.79 * entry.contentRect.height;\n this.containerWidth = Math.min(\n entry.contentRect.width,\n this.maxContainerWidth\n );\n }\n });\n\n override connectedCallback() {\n super.connectedCallback();\n this.resizeObserver.observe(this);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.resizeObserver.unobserve(this);\n }\n\n generateLabels() {\n if (this.containerWidth < 192) {\n return [];\n } else if (this.containerWidth <= 300) {\n return [\n {x: -180, y: LabelPosition.top, text: 'S'},\n {x: -90, y: LabelPosition.top, text: 'W'},\n {x: 0, y: LabelPosition.top, text: 'N'},\n {x: 90, y: LabelPosition.top, text: 'E'},\n {x: 180, y: LabelPosition.top, text: 'S'},\n {x: 270, y: LabelPosition.top, text: 'W'},\n {x: 360, y: LabelPosition.top, text: 'N'},\n {x: 450, y: LabelPosition.top, text: 'E'},\n {x: 540, y: LabelPosition.top, text: 'S'},\n ];\n } else {\n return [\n {x: -180, y: LabelPosition.top, text: 'S'},\n {x: -135, y: LabelPosition.top, text: 'SW'},\n {x: -90, y: LabelPosition.top, text: 'W'},\n {x: -45, y: LabelPosition.top, text: 'NW'},\n {x: 0, y: LabelPosition.top, text: 'N'},\n {x: 45, y: LabelPosition.top, text: 'NE'},\n {x: 90, y: LabelPosition.top, text: 'E'},\n {x: 135, y: LabelPosition.top, text: 'SE'},\n {x: 180, y: LabelPosition.top, text: 'S'},\n {x: 225, y: LabelPosition.top, text: 'SW'},\n {x: 270, y: LabelPosition.top, text: 'W'},\n {x: 315, y: LabelPosition.top, text: 'NW'},\n {x: 360, y: LabelPosition.top, text: 'N'},\n {x: 405, y: LabelPosition.top, text: 'NE'},\n {x: 450, y: LabelPosition.top, text: 'E'},\n {x: 495, y: LabelPosition.top, text: 'SE'},\n {x: 540, y: LabelPosition.top, text: 'S'},\n ];\n }\n }\n\n private generateIntervalTickmarks(scale: number): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n let cardinalInterval = 90;\n\n if (this.containerWidth > 300) {\n cardinalInterval = 45;\n } else if (this.containerWidth < 192) {\n cardinalInterval = 0;\n }\n\n // Guard against zero/negative/non-finite interval to prevent infinite loops\n if (\n !this.tickInterval ||\n this.tickInterval <= 0 ||\n !Number.isFinite(this.tickInterval)\n ) {\n return tickmarks;\n }\n\n for (\n let angle = -180;\n angle < this.maxFOV * 3;\n angle += this.tickInterval\n ) {\n if (cardinalInterval !== 0 && angle % cardinalInterval === 0) {\n continue;\n }\n tickmarks.push({angle: angle * scale, type: TickmarkType.secondary});\n }\n\n return tickmarks;\n }\n\n private generateCardinalTickmarks(\n scale: number,\n labels: Label[]\n ): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n\n for (const label of labels) {\n tickmarks.push({angle: label.x * scale, type: TickmarkType.main});\n }\n\n return tickmarks;\n }\n\n private generateTickmarks(scale: number, labels: Label[]): Tickmark[] {\n return [\n ...this.generateCardinalTickmarks(scale, labels),\n ...this.generateIntervalTickmarks(scale),\n ];\n }\n\n private renderFOVIndicator(): SVGTemplateResult[] {\n const indicators: SVGTemplateResult[] = [];\n\n const maxAdjustment = 10;\n const minContainerWidth = 300;\n const maxContainerWidth = 512;\n\n let yAdjustment = 0;\n if (this.containerWidth < maxContainerWidth) {\n const widthRange = maxContainerWidth - minContainerWidth;\n const scaleFactor =\n (maxContainerWidth - this.containerWidth) / widthRange;\n yAdjustment = scaleFactor * maxAdjustment;\n }\n\n const y = LabelPosition.bottom + yAdjustment + (this.rotType ? 12 : 0);\n\n indicators.push(svg`\n <text x=\"-175\" y=${y} class=\"label left\" fill=${LabelStyle.regular}>\n ${-this.FOV}\\u00B0\n </text>`);\n\n indicators.push(svg`\n <text x=\"0\" y=${y} class=\"label\" fill=${LabelStyle.regular}>\n ${this.heading}\\u00B0\n </text>`);\n\n indicators.push(svg`\n <text x=\"175\" y=${y} class=\"label right\" fill=${LabelStyle.regular}>\n ${this.FOV}\\u00B0\n </text>`);\n\n return indicators;\n }\n\n private priorityFor(element: CompassFlatPriorityElement): 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 arrowColorFor(element: CompassFlatPriorityElement): string {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n }\n\n private get HDGSvg(): SVGTemplateResult {\n return svg`<g transform=\"translate(-24, -74)\">\n <path d=\"M36.7011 44.1445L36.6898 44.1379L36.6781 44.1318L24.2301 37.6823L24.0001 37.5631L23.7701 37.6823L11.3221 44.1318L11.3104 44.1379L11.2991 44.1445C9.25497 45.3438 6.78661 43.308 7.68828 41.0919L22.6036 4.43285C23.1096 3.18905 24.8906 3.18905 25.3967 4.43284L40.3119 41.0919C41.2136 43.308 38.7452 45.3438 36.7011 44.1445Z\" fill=\"${this.arrowColorFor(CompassFlatPriorityElement.hdg)}\" stroke=\"var(--border-silhouette-color)\"/>\n </g>`;\n }\n\n private COGSvg(translation: number): SVGTemplateResult {\n return svg`\n <g transform=\"translate(${-24 + translation}, -74)\">\n <path d=\"M31.9025 36.0262L33.1068 36.6502L32.5956 35.3938L24.4632 15.406L24.0001 14.2677L23.537 15.406L15.4046 35.3938L14.8935 36.6502L16.0978 36.0262L24.0001 31.9319L31.9025 36.0262ZM36.7011 44.1445L36.6898 44.1379L36.6781 44.1318L24.2301 37.6823L24.0001 37.5631L23.7701 37.6823L11.3221 44.1318L11.3104 44.1379L11.2991 44.1445C9.25497 45.3438 6.78661 43.308 7.68828 41.0919L22.6036 4.43285C23.1096 3.18905 24.8906 3.18905 25.3967 4.43284L40.3119 41.0919C41.2136 43.308 38.7452 45.3438 36.7011 44.1445Z\" fill=\"${this.arrowColorFor(CompassFlatPriorityElement.cog)}\" stroke=\"var(--border-silhouette-color)\"/>\n </g>\n `;\n }\n\n override render() {\n let angleDiff = this.courseOverGround - this.heading;\n\n if (angleDiff > this.maxFOV) {\n angleDiff -= 360;\n } else if (angleDiff < -this.maxFOV) {\n angleDiff += 360;\n }\n\n this.FOV = Math.max(this.minFOV, Math.abs(angleDiff));\n\n const baseOffset = 5;\n const translationScale = (baseOffset * 35) / this.FOV;\n\n const translation = angleDiff * translationScale;\n const labels = this.generateLabels();\n const tickmarks = this.generateTickmarks(translationScale, labels);\n const scaledLabels = labels.map((l) => ({\n ...l,\n x: l.x * translationScale,\n }));\n\n const hasBottomBar = !!this.rotType;\n const arrowViewBoxY = hasBottomBar\n ? -128 + Math.round((12 * 384) / 352)\n : -128;\n const viewBox = `-192 ${arrowViewBoxY} 384 128`;\n\n return html`\n <div class=\"container\" style=\"max-width:${this.maxContainerWidth}px\">\n <obc-watch-flat\n .FOVIndicator=${this.FOVIndicator ? this.renderFOVIndicator() : []}\n .labels=${scaledLabels}\n .rotation=${this.heading}\n .tickmarks=${tickmarks}\n .tickmarkSpacing=${translationScale}\n .bottomBar=${!!this.rotType}\n .rotType=${this.rotType}\n .rotStartX=${0}\n .rotEndX=${(this.rotationsPerMinute / (this.rotMaxValue || 1)) *\n this.rotArcExtent *\n translationScale}\n .rotDotSpacing=${LINEAR_DOT_ANGLE_SPACING * translationScale}\n .rotationsPerMinute=${this.rotationsPerMinute}\n .rotPriority=${this.priorityFor(CompassFlatPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband * translationScale}\n ></obc-watch-flat>\n <svg viewBox=${viewBox} xmlns=\"http://www.w3.org/2000/svg\">\n ${this.HDGSvg}${this.COGSvg(translation)}\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass-flat': ObcCompassFlat;\n }\n}\n"],"names":["CompassFlatPriorityElement","LabelPosition","LabelStyle"],"mappings":";;;;;;;;;;;;;;;;;;;AAeO,IAAK,+CAAAA,gCAAL;AACLA,8BAAA,KAAA,IAAM;AACNA,8BAAA,KAAA,IAAM;AACNA,8BAAA,KAAA,IAAM;AAHI,SAAAA;AAAA,GAAA,8BAAA,CAAA,CAAA;AAML,IAAK,kCAAAC,mBAAL;AACLA,iBAAAA,eAAA,SAAM,GAAA,IAAN;AACAA,iBAAAA,eAAA,YAAS,EAAA,IAAT;AAFU,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,IAAK,+BAAAC,gBAAL;AACLA,cAAA,SAAA,IAAU;AADA,SAAAA;AAAA,GAAA,cAAA,CAAA,CAAA;AA6CL,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAAxC,cAAA;AAAA,UAAA,GAAA,SAAA;AACsB,SAAA,eAAwB;AACzB,SAAA,UAAU;AACV,SAAA,mBAAmB;AACnB,SAAA,eAAe;AACf,SAAA,MAAM;AACN,SAAA,SAAS;AACT,SAAA,SAAS;AACT,SAAA,WAAqB,SAAS;AAExD,SAAA,mBAAiD;AAAA,MAC/C;AAAA;AAAA,IAAA;AAGwB,SAAA,qBAA6B;AAC7B,SAAA,cAAsB;AACtB,SAAA,eAAuB;AACtB,SAAA,mBAA4B;AAC7B,SAAA,oBAA4B;AAE7C,SAAQ,iBAAiB;AACzB,SAAQ,oBAAoB;AAErC,SAAQ,iBAAiC,IAAI,eAAe,CAAC,YAAY;AACvE,iBAAW,SAAS,SAAS;AAE3B,aAAK,oBAAoB,UAAU,OAAO,MAAM,YAAY;AAC5D,aAAK,iBAAiB,KAAK;AAAA,UACzB,MAAM,YAAY;AAAA,UAClB,KAAK;AAAA,QAAA;AAAA,MAET;AAAA,IACF,CAAC;AAAA,EAAA;AAAA,EAEQ,oBAAoB;AAC3B,UAAM,kBAAA;AACN,SAAK,eAAe,QAAQ,IAAI;AAAA,EAClC;AAAA,EAES,uBAAuB;AAC9B,UAAM,qBAAA;AACN,SAAK,eAAe,UAAU,IAAI;AAAA,EACpC;AAAA,EAEA,iBAAiB;AACf,QAAI,KAAK,iBAAiB,KAAK;AAC7B,aAAO,CAAA;AAAA,IACT,WAAW,KAAK,kBAAkB,KAAK;AACrC,aAAO;AAAA,QACL,EAAC,GAAG,MAAM,GAAG,KAAmB,MAAM,IAAA;AAAA,QACtC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,GAAG,GAAG,KAAmB,MAAM,IAAA;AAAA,QACnC,EAAC,GAAG,IAAI,GAAG,KAAmB,MAAM,IAAA;AAAA,QACpC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,MAAG;AAAA,IAE5C,OAAO;AACL,aAAO;AAAA,QACL,EAAC,GAAG,MAAM,GAAG,KAAmB,MAAM,IAAA;AAAA,QACtC,EAAC,GAAG,MAAM,GAAG,KAAmB,MAAM,KAAA;AAAA,QACtC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,GAAG,GAAG,KAAmB,MAAM,IAAA;AAAA,QACnC,EAAC,GAAG,IAAI,GAAG,KAAmB,MAAM,KAAA;AAAA,QACpC,EAAC,GAAG,IAAI,GAAG,KAAmB,MAAM,IAAA;AAAA,QACpC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,KAAA;AAAA,QACrC,EAAC,GAAG,KAAK,GAAG,KAAmB,MAAM,IAAA;AAAA,MAAG;AAAA,IAE5C;AAAA,EACF;AAAA,EAEQ,0BAA0B,OAA2B;AAC3D,UAAM,YAAwB,CAAA;AAC9B,QAAI,mBAAmB;AAEvB,QAAI,KAAK,iBAAiB,KAAK;AAC7B,yBAAmB;AAAA,IACrB,WAAW,KAAK,iBAAiB,KAAK;AACpC,yBAAmB;AAAA,IACrB;AAGA,QACE,CAAC,KAAK,gBACN,KAAK,gBAAgB,KACrB,CAAC,OAAO,SAAS,KAAK,YAAY,GAClC;AACA,aAAO;AAAA,IACT;AAEA,aACM,QAAQ,MACZ,QAAQ,KAAK,SAAS,GACtB,SAAS,KAAK,cACd;AACA,UAAI,qBAAqB,KAAK,QAAQ,qBAAqB,GAAG;AAC5D;AAAA,MACF;AACA,gBAAU,KAAK,EAAC,OAAO,QAAQ,OAAO,MAAM,aAAa,WAAU;AAAA,IACrE;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,0BACN,OACA,QACY;AACZ,UAAM,YAAwB,CAAA;AAE9B,eAAW,SAAS,QAAQ;AAC1B,gBAAU,KAAK,EAAC,OAAO,MAAM,IAAI,OAAO,MAAM,aAAa,MAAK;AAAA,IAClE;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,OAAe,QAA6B;AACpE,WAAO;AAAA,MACL,GAAG,KAAK,0BAA0B,OAAO,MAAM;AAAA,MAC/C,GAAG,KAAK,0BAA0B,KAAK;AAAA,IAAA;AAAA,EAE3C;AAAA,EAEQ,qBAA0C;AAChD,UAAM,aAAkC,CAAA;AAExC,UAAM,gBAAgB;AACtB,UAAM,oBAAoB;AAC1B,UAAM,oBAAoB;AAE1B,QAAI,cAAc;AAClB,QAAI,KAAK,iBAAiB,mBAAmB;AAC3C,YAAM,aAAa,oBAAoB;AACvC,YAAM,eACH,oBAAoB,KAAK,kBAAkB;AAC9C,oBAAc,cAAc;AAAA,IAC9B;AAEA,UAAM,IAAI,KAAuB,eAAe,KAAK,UAAU,KAAK;AAEpE,eAAW,KAAK;AAAA,6BACS,CAAC,4BAA4B,6CAAA;AAAA,cAC5C,CAAC,KAAK,GAAG;AAAA,kBACL;AAEd,eAAW,KAAK;AAAA,0BACM,CAAC,uBAAuB,6CAAA;AAAA,cACpC,KAAK,OAAO;AAAA,kBACR;AAEd,eAAW,KAAK;AAAA,4BACQ,CAAC,6BAA6B,6CAAA;AAAA,cAC5C,KAAK,GAAG;AAAA,kBACJ;AAEd,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,SAA+C;AACjE,UAAM,WAAW,MAAM,QAAQ,KAAK,gBAAgB,IAChD,KAAK,mBACL,CAAA;AACJ,WAAO,SAAS,SAAS,OAAO,IAAI,KAAK,WAAW,SAAS;AAAA,EAC/D;AAAA,EAEQ,cAAc,SAA6C;AACjE,WAAO,KAAK,YAAY,OAAO,MAAM,SAAS,WAC1C,+CACA;AAAA,EACN;AAAA,EAEA,IAAY,SAA4B;AACtC,WAAO;AAAA,4VACiV,KAAK;AAAA,MAAc;AAAA;AAAA,KAA+B;AAAA;AAAA,EAE5Y;AAAA,EAEQ,OAAO,aAAwC;AACrD,WAAO;AAAA,gCACqB,MAAM,WAAW;AAAA,wgBACud,KAAK;AAAA,MAAc;AAAA;AAAA,KAA+B;AAAA;AAAA;AAAA,EAGxjB;AAAA,EAES,SAAS;AAChB,QAAI,YAAY,KAAK,mBAAmB,KAAK;AAE7C,QAAI,YAAY,KAAK,QAAQ;AAC3B,mBAAa;AAAA,IACf,WAAW,YAAY,CAAC,KAAK,QAAQ;AACnC,mBAAa;AAAA,IACf;AAEA,SAAK,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,SAAS,CAAC;AAEpD,UAAM,aAAa;AACnB,UAAM,mBAAoB,aAAa,KAAM,KAAK;AAElD,UAAM,cAAc,YAAY;AAChC,UAAM,SAAS,KAAK,eAAA;AACpB,UAAM,YAAY,KAAK,kBAAkB,kBAAkB,MAAM;AACjE,UAAM,eAAe,OAAO,IAAI,CAAC,OAAO;AAAA,MACtC,GAAG;AAAA,MACH,GAAG,EAAE,IAAI;AAAA,IAAA,EACT;AAEF,UAAM,eAAe,CAAC,CAAC,KAAK;AAC5B,UAAM,gBAAgB,eAClB,OAAO,KAAK,MAAO,KAAK,MAAO,GAAG,IAClC;AACJ,UAAM,UAAU,QAAQ,aAAa;AAErC,WAAO;AAAA,gDACqC,KAAK,iBAAiB;AAAA;AAAA,0BAE5C,KAAK,eAAe,KAAK,mBAAA,IAAuB,CAAA,CAAE;AAAA,oBACxD,YAAY;AAAA,sBACV,KAAK,OAAO;AAAA,uBACX,SAAS;AAAA,6BACH,gBAAgB;AAAA,uBACtB,CAAC,CAAC,KAAK,OAAO;AAAA,qBAChB,KAAK,OAAO;AAAA,uBACV,CAAC;AAAA,qBACF,KAAK,sBAAsB,KAAK,eAAe,KAC3D,KAAK,eACL,gBAAgB;AAAA,2BACC,2BAA2B,gBAAgB;AAAA,gCACtC,KAAK,kBAAkB;AAAA,yBAC9B,KAAK;AAAA,MAAY;AAAA;AAAA,IAAA,CAA+B;AAAA,8BAC3C,KAAK,gBAAgB;AAAA,+BACpB,KAAK,oBAAoB,gBAAgB;AAAA;AAAA,uBAEjD,OAAO;AAAA,YAClB,KAAK,MAAM,GAAG,KAAK,OAAO,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA,EAIhD;AAGF;AA7Pa,eA4PK,SAAS,UAAU,cAAc;AA3PtB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GADd,eACgB,WAAA,gBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,eAEe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,eAGe,WAAA,oBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,eAIe,WAAA,gBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,eAKe,WAAA,OAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,eAMe,WAAA,UAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,eAOe,WAAA,UAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GARb,eAQe,WAAA,YAAA,CAAA;AAE1B,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAT9B,eAUX,WAAA,oBAAA,CAAA;AAG0B,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAbb,eAae,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAdb,eAce,WAAA,sBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAfb,eAee,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhBb,eAgBe,WAAA,gBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAjBd,eAiBgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlBb,eAkBe,WAAA,qBAAA,CAAA;AAET,gBAAA;AAAA,EAAhB,MAAA;AAAM,GApBI,eAoBM,WAAA,kBAAA,CAAA;AACA,gBAAA;AAAA,EAAhB,MAAA;AAAM,GArBI,eAqBM,WAAA,qBAAA,CAAA;AArBN,iBAAN,gBAAA;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB,cAAA;"}
@@ -66,6 +66,7 @@ export declare class ObcCompassSector extends LitElement {
66
66
  rotationsPerMinute: number;
67
67
  rotMaxValue: number;
68
68
  rotPortStarboard: boolean;
69
+ rotAtZeroDeadband: number;
69
70
  state: InstrumentState;
70
71
  priority: Priority;
71
72
  priorityElements: CompassSectorPriorityElement[];
@@ -1 +1 @@
1
- {"version":3,"file":"compass-sector.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass-sector/compass-sector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAgC,MAAM,KAAK,CAAC;AAG9E,OAAO,mBAAmB,CAAC;AAG3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAKL,OAAO,EACP,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,CAAC;AAE9B,oBAAY,4BAA4B;IACtC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IACpB,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,UAAQ;IAChD,6BAA6B,EAAE,MAAM,CAAK;IACzC,eAAe,EAAE,OAAO,CAAS;IACjC,QAAQ,EAAE,OAAO,CAAS;IACV,cAAc,EAAE,WAAW,EAAE,CAAM;IAEpD,MAAM,EAAE,MAAM,CAAM;IAEpB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,WAAW,CAA2B;IACnD,kBAAkB,EAAE,MAAM,CAAK;IAC/B,WAAW,EAAE,MAAM,CAAM;IACxB,gBAAgB,EAAE,OAAO,CAAS;IAEnC,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,4BAA4B,EAAE,CAE9C;IACyB,eAAe,EAAE,OAAO,CAAS;IACjC,YAAY,EAAE,OAAO,CAAS;IAEzD,OAAO,CAAC,UAAU,CAGf;IAGH,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,cAAc,CAAwB;IAErC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA8DzC,oBAAoB,IAAI,IAAI;IASrC,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,eAAe;IAmDvB,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAgBrB,OAAO,KAAK,YAAY,GAIvB;IAED,OAAO,CAAC,WAAW;IAWV,MAAM;IAmEf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,oBAAoB,EAAE,gBAAgB,CAAC;KACxC;CACF"}
1
+ {"version":3,"file":"compass-sector.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass-sector/compass-sector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAgC,MAAM,KAAK,CAAC;AAG9E,OAAO,mBAAmB,CAAC;AAG3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAKL,OAAO,EACP,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,CAAC;AAE9B,oBAAY,4BAA4B;IACtC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;CACZ;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBACa,gBAAiB,SAAQ,UAAU;IACpB,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,UAAQ;IAChD,6BAA6B,EAAE,MAAM,CAAK;IACzC,eAAe,EAAE,OAAO,CAAS;IACjC,QAAQ,EAAE,OAAO,CAAS;IACV,cAAc,EAAE,WAAW,EAAE,CAAM;IAEpD,MAAM,EAAE,MAAM,CAAM;IAEpB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,WAAW,CAA2B;IACnD,kBAAkB,EAAE,MAAM,CAAK;IAC/B,WAAW,EAAE,MAAM,CAAM;IACxB,gBAAgB,EAAE,OAAO,CAAS;IACnC,iBAAiB,EAAE,MAAM,CAAyB;IAElD,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,4BAA4B,EAAE,CAE9C;IACyB,eAAe,EAAE,OAAO,CAAS;IACjC,YAAY,EAAE,OAAO,CAAS;IAEzD,OAAO,CAAC,UAAU,CAGf;IAGH,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,cAAc,CAAwB;IAErC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA8DzC,oBAAoB,IAAI,IAAI;IASrC,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,eAAe;IAmDvB,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAgBrB,OAAO,KAAK,YAAY,GAIvB;IAED,OAAO,CAAC,WAAW;IAWV,MAAM;IAoEf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,oBAAoB,EAAE,gBAAgB,CAAC;KACxC;CACF"}
@@ -7,10 +7,10 @@ import { arrow, ArrowStyle } from "../compass/arrow.js";
7
7
  import { AdviceState } from "../watch/advice.js";
8
8
  import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
9
9
  import { computeZoomToFitArcFrame } from "../../svghelpers/arc-frame.js";
10
+ import { RotPosition, ROT_ZERO_DEADBAND_DEG } from "../rate-of-turn/rot-renderer.js";
11
+ import { RotType } from "../rate-of-turn/rot-renderer.js";
10
12
  import { customElement } from "../../decorator.js";
11
13
  import { InstrumentState, Priority } from "../types.js";
12
- import { RotPosition } from "../rate-of-turn/rot-renderer.js";
13
- import { RotType } from "../rate-of-turn/rot-renderer.js";
14
14
  var __defProp = Object.defineProperty;
15
15
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
16
16
  var __decorateClass = (decorators, target, key, kind) => {
@@ -64,6 +64,7 @@ let ObcCompassSector = class extends LitElement {
64
64
  this.rotationsPerMinute = 1;
65
65
  this.rotMaxValue = 10;
66
66
  this.rotPortStarboard = false;
67
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_DEG;
67
68
  this.state = InstrumentState.active;
68
69
  this.priority = Priority.regular;
69
70
  this.priorityElements = [
@@ -299,6 +300,7 @@ let ObcCompassSector = class extends LitElement {
299
300
  /* rot */
300
301
  )}
301
302
  .rotPortStarboard=${this.rotPortStarboard}
303
+ .rotAtZeroDeadband=${this.rotAtZeroDeadband}
302
304
  .rotationsPerMinute=${this.rotationsPerMinute}
303
305
  >
304
306
  </obc-watch>
@@ -382,6 +384,9 @@ __decorateClass([
382
384
  __decorateClass([
383
385
  property({ type: Boolean })
384
386
  ], ObcCompassSector.prototype, "rotPortStarboard", 2);
387
+ __decorateClass([
388
+ property({ type: Number })
389
+ ], ObcCompassSector.prototype, "rotAtZeroDeadband", 2);
385
390
  __decorateClass([
386
391
  property({ type: String })
387
392
  ], ObcCompassSector.prototype, "state", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"compass-sector.js","sources":["../../../src/navigation-instruments/compass-sector/compass-sector.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, svg, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './compass-sector.css?inline';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType, TickmarkStyle} from '../watch/tickmark.js';\nimport {arrow, ArrowStyle} from '../compass/arrow.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {\n WatchCircleType,\n WatchArea,\n OUTER_RING_RADIUS,\n innerRingRadiusFor,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {\n computeZoomToFitArcFrame,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType, RotPosition};\n\nexport enum CompassSectorPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n}\n\nconst PADDING = 72;\nconst WATCH_TYPE = WatchCircleType.triple;\nconst INNER_RADIUS = innerRingRadiusFor(WATCH_TYPE);\n/** Half of the fixed 120° arc on the watch face. */\nconst ARC_HALF_EXTENT = 60;\n\ninterface TickDensity {\n mainInterval: number;\n primaryInterval: number;\n secondaryInterval: number | undefined;\n}\n\nfunction tickDensityForFOV(fov: number): TickDensity {\n if (fov <= 30) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: 1};\n } else if (fov <= 60) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: undefined};\n } else if (fov <= 120) {\n return {mainInterval: 30, primaryInterval: 10, secondaryInterval: 5};\n } else {\n return {mainInterval: 90, primaryInterval: 30, secondaryInterval: 10};\n }\n}\n\nfunction normalizeAngle(a: number): number {\n return ((a % 360) + 360) % 360;\n}\n\n/**\n * `<obc-compass-sector>` — Curved compass strip that auto‑scales to keep HDG and COG visible.\n *\n * Renders a fixed 120° arc of a triple‑ring compass face. The visible\n * compass range (field of view) adjusts automatically so that both the\n * heading (HDG) and course‑over‑ground (COG) arrows are always in view.\n * This is the radial equivalent of `<obc-compass-flat>`: the arc shape\n * never changes — only the scale (compass‑degrees per arc‑degree) changes.\n *\n * ## Features\n *\n * - **Fixed 120° arc**: The watch face is always a 120° sector (±60° from\n * center), identical in shape to `<obc-rot-sector>`.\n * - **FOV auto‑scaling**: The field of view widens when the HDG–COG\n * angular difference grows, compressing more compass degrees into the\n * fixed arc. Tickmark density adjusts automatically.\n * - **HDG / COG arrows**: Solid (HDG) arrow is always at the arc center.\n * Hollow (COG) arrow is positioned proportionally within the arc.\n * - **North arrow**: A gray triangle in the outer scale band indicates\n * north when it falls within the visible FOV.\n * - **Heading setpoint**: Optional setpoint marker with auto at‑setpoint\n * detection and confirm animation, positioned at the mapped arc angle.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs,\n * mapped into the scaled arc.\n * - **Rate of turn**: Animated ROT indicator (dots or bar) spanning from\n * HDG to the mapped COG position, clipped to the arc.\n * - **Zoom to fit**: When `zoomToFitArc` is `true`, the fixed 120° arc is\n * enlarged to fill the available space.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to sensor values in degrees.\n * - Adjust `minFOV` to control the minimum zoom level (default 30°).\n * - Enable `zoomToFitArc` to enlarge the arc to fill the viewport.\n * - For a full‑circle compass, use `<obc-compass>` instead.\n *\n * @fires None\n */\n@customElement('obc-compass-sector')\nexport class ObcCompassSector 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 = 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\n @property({type: Number}) minFOV: number = 30;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: Number}) rotMaxValue: number = 10;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassSectorPriorityElement[] = [\n CompassSectorPriorityElement.hdg,\n ];\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n // Cached computed values — updated in willUpdate()\n private _halfFOV = 30;\n private _arcHalfExtent = ARC_HALF_EXTENT;\n private _scale = 1;\n private _radiusOffset = 0;\n private _cachedViewBox = '';\n private _cachedArcFrame: ZoomToFitArcFrame | undefined;\n private _cachedAreas: WatchArea[] = [];\n private _cachedTickmarks: Tickmark[] = [];\n private _cachedAdvices: AngleAdviceRaw[] = [];\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 const arcInputsChanged =\n changed.has('heading') ||\n changed.has('courseOverGround') ||\n changed.has('minFOV') ||\n changed.has('zoomToFitArc');\n\n if (arcInputsChanged) {\n let diff = this.courseOverGround - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n const minFov = Math.max(1, this.minFOV);\n const MARGIN = 15;\n\n if (this.zoomToFitArc) {\n const needed = Math.max(minFov, Math.abs(diff) + MARGIN);\n if (needed <= ARC_HALF_EXTENT) {\n this._halfFOV = needed;\n this._arcHalfExtent = needed;\n this._scale = 1;\n } else {\n this._halfFOV = needed;\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / needed;\n }\n } else {\n this._halfFOV = Math.max(minFov, Math.abs(diff));\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / this._halfFOV;\n }\n\n this._cachedAreas = [\n {\n startAngle: this.heading - this._arcHalfExtent,\n endAngle: this.heading + this._arcHalfExtent,\n roundInsideCut: true,\n roundOutsideCut: true,\n },\n ];\n\n this._computeViewBox();\n this._cachedTickmarks = this._buildTickmarks();\n }\n\n if (arcInputsChanged || changed.has('headingAdvices')) {\n this._cachedAdvices = this._buildAdvices();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // ---------------------------------------------------------------------------\n // Angle mapping — maps compass degrees to arc positions\n // ---------------------------------------------------------------------------\n\n private _mapAngle(compassDeg: number): number {\n let diff = compassDeg - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n return this.heading + diff * this._scale;\n }\n\n // ---------------------------------------------------------------------------\n // Areas — fixed 120° arc centered on heading (built in willUpdate)\n // ---------------------------------------------------------------------------\n\n // ---------------------------------------------------------------------------\n // Tickmarks — compass-degree labels at mapped arc positions\n // ---------------------------------------------------------------------------\n\n private _buildTickmarks(): Tickmark[] {\n const fov = this._halfFOV * 2;\n const {mainInterval, primaryInterval, secondaryInterval} =\n tickDensityForFOV(fov);\n const halfFov = this._halfFOV;\n const compassStart = this.heading - halfFov;\n const compassEnd = this.heading + halfFov;\n\n const tickmarks: Tickmark[] = [];\n const added = new Set<number>();\n\n const addTick = (\n arcAngle: number,\n type: TickmarkType,\n text?: string\n ): void => {\n const key = Math.round(arcAngle * 1000);\n if (added.has(key)) return;\n added.add(key);\n tickmarks.push({angle: arcAngle, type, text});\n };\n\n const step = secondaryInterval ?? primaryInterval;\n const firstTick = Math.ceil(compassStart / step) * step;\n\n for (\n let compassDeg = firstTick;\n compassDeg <= compassEnd;\n compassDeg += step\n ) {\n const norm = normalizeAngle(compassDeg);\n const arcAngle = this._mapAngle(compassDeg);\n const isMain = norm % mainInterval === 0;\n const isPrimary = norm % primaryInterval === 0;\n\n if (isMain) {\n addTick(arcAngle, TickmarkType.main, Math.round(norm).toString());\n } else if (isPrimary) {\n addTick(arcAngle, TickmarkType.primary);\n } else {\n addTick(arcAngle, TickmarkType.secondary);\n }\n }\n\n return tickmarks;\n }\n\n // ---------------------------------------------------------------------------\n // ViewBox\n // ---------------------------------------------------------------------------\n\n private _computeViewBox(): void {\n if (this.zoomToFitArc) {\n const targetSize = (176 + PADDING) * 2;\n const frame = computeZoomToFitArcFrame({\n areas: this._cachedAreas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: INNER_RADIUS,\n extension: PADDING,\n targetSize,\n });\n this._radiusOffset = frame.radiusOffset;\n this._cachedViewBox = frame.viewBox;\n this._cachedArcFrame = frame;\n } else {\n this._radiusOffset = 0;\n const width = (176 + PADDING) * 2;\n this._cachedViewBox = `-${width / 2} -${width / 2} ${width} ${width}`;\n this._cachedArcFrame = undefined;\n }\n }\n\n // ---------------------------------------------------------------------------\n // North arrow — rendered in overlay at mapped 0° position\n // ---------------------------------------------------------------------------\n\n private _renderNorthArrow(rOff: number) {\n let northOffset = -this.heading;\n if (northOffset > 180) northOffset -= 360;\n else if (northOffset < -180) northOffset += 360;\n if (Math.abs(northOffset) > this._halfFOV) return nothing;\n\n const northArcAngle = this._mapAngle(0);\n const radius = OUTER_RING_RADIUS + rOff;\n return svg`\n <g transform=\"rotate(${northArcAngle}) translate(0, ${-radius})\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M-17.8457 24.984 0 0 17.8458 24.984C11.9868 24.3338 6.0324 24 0 24-6.0323 24-11.9867 24.3338-17.8457 24.984Z\"\n fill=\"var(--instrument-frame-tertiary-color)\"/>\n </g>\n `;\n }\n\n // ---------------------------------------------------------------------------\n // Priority & advice helpers\n // ---------------------------------------------------------------------------\n\n private _angleInRange(value: number, min: number, max: number): boolean {\n const v = normalizeAngle(value);\n const start = normalizeAngle(min);\n const end = normalizeAngle(max);\n return start <= end ? v >= start && v <= end : v >= start || v <= end;\n }\n\n private _buildAdvices(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state = this._angleInRange(this.heading, minAngle, maxAngle)\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {\n minAngle: this._mapAngle(minAngle),\n maxAngle: this._mapAngle(maxAngle),\n type,\n state,\n };\n });\n }\n\n private get _rotEndAngle(): number {\n const maxVal = this.rotMaxValue || 1;\n const barCompassDeg = (this.rotationsPerMinute / maxVal) * ARC_HALF_EXTENT;\n return this._mapAngle(this.heading + barCompassDeg);\n }\n\n private priorityFor(element: CompassSectorPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n // ---------------------------------------------------------------------------\n // Render\n // ---------------------------------------------------------------------------\n\n override render() {\n const rotation = -this.heading;\n const viewBox = this._cachedViewBox;\n const rOff = this._radiusOffset;\n\n const mappedCOG = this._mapAngle(this.courseOverGround);\n const mappedSetpoint =\n this.headingSetpoint != null\n ? this._mapAngle(this.headingSetpoint)\n : undefined;\n const mappedNewSetpoint =\n this.newHeadingSetpoint != null\n ? this._mapAngle(this.newHeadingSetpoint)\n : undefined;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .padding=${PADDING}\n .advices=${this._cachedAdvices}\n .tickmarks=${this._cachedTickmarks}\n .tickmarkStyle=${TickmarkStyle.regular}\n .tickmarksInside=${this.tickmarksInside}\n .state=${this.state}\n .watchCircleType=${WATCH_TYPE}\n .northArrow=${false}\n .areas=${this._cachedAreas}\n .arcFrame=${this._cachedArcFrame}\n .zoomToFitArc=${this.zoomToFitArc}\n .tickFadeAngle=${this._arcHalfExtent * 0.2}\n .rotation=${rotation}\n .angleSetpoint=${mappedSetpoint}\n .newAngleSetpoint=${mappedNewSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading}\n .rotEndAngle=${this._rotEndAngle}\n .rotPriority=${this.priorityFor(CompassSectorPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\" transform=\"rotate(${rotation})\">\n ${this._renderNorthArrow(rOff)}\n ${arrow(\n ArrowStyle.HDG,\n this.heading,\n this.priorityFor(CompassSectorPriorityElement.hdg),\n rOff\n )}\n ${arrow(\n ArrowStyle.COG,\n mappedCOG,\n this.priorityFor(CompassSectorPriorityElement.cog),\n rOff\n )}\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass-sector': ObcCompassSector;\n }\n}\n"],"names":["CompassSectorPriorityElement"],"mappings":"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"}
1
+ {"version":3,"file":"compass-sector.js","sources":["../../../src/navigation-instruments/compass-sector/compass-sector.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, svg, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './compass-sector.css?inline';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType, TickmarkStyle} from '../watch/tickmark.js';\nimport {arrow, ArrowStyle} from '../compass/arrow.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {\n WatchCircleType,\n WatchArea,\n OUTER_RING_RADIUS,\n innerRingRadiusFor,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {\n computeZoomToFitArcFrame,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\nimport {ROT_ZERO_DEADBAND_DEG} from '../rate-of-turn/rot-renderer.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType, RotPosition};\n\nexport enum CompassSectorPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n}\n\nconst PADDING = 72;\nconst WATCH_TYPE = WatchCircleType.triple;\nconst INNER_RADIUS = innerRingRadiusFor(WATCH_TYPE);\n/** Half of the fixed 120° arc on the watch face. */\nconst ARC_HALF_EXTENT = 60;\n\ninterface TickDensity {\n mainInterval: number;\n primaryInterval: number;\n secondaryInterval: number | undefined;\n}\n\nfunction tickDensityForFOV(fov: number): TickDensity {\n if (fov <= 30) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: 1};\n } else if (fov <= 60) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: undefined};\n } else if (fov <= 120) {\n return {mainInterval: 30, primaryInterval: 10, secondaryInterval: 5};\n } else {\n return {mainInterval: 90, primaryInterval: 30, secondaryInterval: 10};\n }\n}\n\nfunction normalizeAngle(a: number): number {\n return ((a % 360) + 360) % 360;\n}\n\n/**\n * `<obc-compass-sector>` — Curved compass strip that auto‑scales to keep HDG and COG visible.\n *\n * Renders a fixed 120° arc of a triple‑ring compass face. The visible\n * compass range (field of view) adjusts automatically so that both the\n * heading (HDG) and course‑over‑ground (COG) arrows are always in view.\n * This is the radial equivalent of `<obc-compass-flat>`: the arc shape\n * never changes — only the scale (compass‑degrees per arc‑degree) changes.\n *\n * ## Features\n *\n * - **Fixed 120° arc**: The watch face is always a 120° sector (±60° from\n * center), identical in shape to `<obc-rot-sector>`.\n * - **FOV auto‑scaling**: The field of view widens when the HDG–COG\n * angular difference grows, compressing more compass degrees into the\n * fixed arc. Tickmark density adjusts automatically.\n * - **HDG / COG arrows**: Solid (HDG) arrow is always at the arc center.\n * Hollow (COG) arrow is positioned proportionally within the arc.\n * - **North arrow**: A gray triangle in the outer scale band indicates\n * north when it falls within the visible FOV.\n * - **Heading setpoint**: Optional setpoint marker with auto at‑setpoint\n * detection and confirm animation, positioned at the mapped arc angle.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs,\n * mapped into the scaled arc.\n * - **Rate of turn**: Animated ROT indicator (dots or bar) spanning from\n * HDG to the mapped COG position, clipped to the arc.\n * - **Zoom to fit**: When `zoomToFitArc` is `true`, the fixed 120° arc is\n * enlarged to fill the available space.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to sensor values in degrees.\n * - Adjust `minFOV` to control the minimum zoom level (default 30°).\n * - Enable `zoomToFitArc` to enlarge the arc to fill the viewport.\n * - For a full‑circle compass, use `<obc-compass>` instead.\n *\n * @fires None\n */\n@customElement('obc-compass-sector')\nexport class ObcCompassSector 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 = 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\n @property({type: Number}) minFOV: number = 30;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: Number}) rotMaxValue: number = 10;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\n\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassSectorPriorityElement[] = [\n CompassSectorPriorityElement.hdg,\n ];\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n // Cached computed values — updated in willUpdate()\n private _halfFOV = 30;\n private _arcHalfExtent = ARC_HALF_EXTENT;\n private _scale = 1;\n private _radiusOffset = 0;\n private _cachedViewBox = '';\n private _cachedArcFrame: ZoomToFitArcFrame | undefined;\n private _cachedAreas: WatchArea[] = [];\n private _cachedTickmarks: Tickmark[] = [];\n private _cachedAdvices: AngleAdviceRaw[] = [];\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 const arcInputsChanged =\n changed.has('heading') ||\n changed.has('courseOverGround') ||\n changed.has('minFOV') ||\n changed.has('zoomToFitArc');\n\n if (arcInputsChanged) {\n let diff = this.courseOverGround - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n const minFov = Math.max(1, this.minFOV);\n const MARGIN = 15;\n\n if (this.zoomToFitArc) {\n const needed = Math.max(minFov, Math.abs(diff) + MARGIN);\n if (needed <= ARC_HALF_EXTENT) {\n this._halfFOV = needed;\n this._arcHalfExtent = needed;\n this._scale = 1;\n } else {\n this._halfFOV = needed;\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / needed;\n }\n } else {\n this._halfFOV = Math.max(minFov, Math.abs(diff));\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / this._halfFOV;\n }\n\n this._cachedAreas = [\n {\n startAngle: this.heading - this._arcHalfExtent,\n endAngle: this.heading + this._arcHalfExtent,\n roundInsideCut: true,\n roundOutsideCut: true,\n },\n ];\n\n this._computeViewBox();\n this._cachedTickmarks = this._buildTickmarks();\n }\n\n if (arcInputsChanged || changed.has('headingAdvices')) {\n this._cachedAdvices = this._buildAdvices();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // ---------------------------------------------------------------------------\n // Angle mapping — maps compass degrees to arc positions\n // ---------------------------------------------------------------------------\n\n private _mapAngle(compassDeg: number): number {\n let diff = compassDeg - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n return this.heading + diff * this._scale;\n }\n\n // ---------------------------------------------------------------------------\n // Areas — fixed 120° arc centered on heading (built in willUpdate)\n // ---------------------------------------------------------------------------\n\n // ---------------------------------------------------------------------------\n // Tickmarks — compass-degree labels at mapped arc positions\n // ---------------------------------------------------------------------------\n\n private _buildTickmarks(): Tickmark[] {\n const fov = this._halfFOV * 2;\n const {mainInterval, primaryInterval, secondaryInterval} =\n tickDensityForFOV(fov);\n const halfFov = this._halfFOV;\n const compassStart = this.heading - halfFov;\n const compassEnd = this.heading + halfFov;\n\n const tickmarks: Tickmark[] = [];\n const added = new Set<number>();\n\n const addTick = (\n arcAngle: number,\n type: TickmarkType,\n text?: string\n ): void => {\n const key = Math.round(arcAngle * 1000);\n if (added.has(key)) return;\n added.add(key);\n tickmarks.push({angle: arcAngle, type, text});\n };\n\n const step = secondaryInterval ?? primaryInterval;\n const firstTick = Math.ceil(compassStart / step) * step;\n\n for (\n let compassDeg = firstTick;\n compassDeg <= compassEnd;\n compassDeg += step\n ) {\n const norm = normalizeAngle(compassDeg);\n const arcAngle = this._mapAngle(compassDeg);\n const isMain = norm % mainInterval === 0;\n const isPrimary = norm % primaryInterval === 0;\n\n if (isMain) {\n addTick(arcAngle, TickmarkType.main, Math.round(norm).toString());\n } else if (isPrimary) {\n addTick(arcAngle, TickmarkType.primary);\n } else {\n addTick(arcAngle, TickmarkType.secondary);\n }\n }\n\n return tickmarks;\n }\n\n // ---------------------------------------------------------------------------\n // ViewBox\n // ---------------------------------------------------------------------------\n\n private _computeViewBox(): void {\n if (this.zoomToFitArc) {\n const targetSize = (176 + PADDING) * 2;\n const frame = computeZoomToFitArcFrame({\n areas: this._cachedAreas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: INNER_RADIUS,\n extension: PADDING,\n targetSize,\n });\n this._radiusOffset = frame.radiusOffset;\n this._cachedViewBox = frame.viewBox;\n this._cachedArcFrame = frame;\n } else {\n this._radiusOffset = 0;\n const width = (176 + PADDING) * 2;\n this._cachedViewBox = `-${width / 2} -${width / 2} ${width} ${width}`;\n this._cachedArcFrame = undefined;\n }\n }\n\n // ---------------------------------------------------------------------------\n // North arrow — rendered in overlay at mapped 0° position\n // ---------------------------------------------------------------------------\n\n private _renderNorthArrow(rOff: number) {\n let northOffset = -this.heading;\n if (northOffset > 180) northOffset -= 360;\n else if (northOffset < -180) northOffset += 360;\n if (Math.abs(northOffset) > this._halfFOV) return nothing;\n\n const northArcAngle = this._mapAngle(0);\n const radius = OUTER_RING_RADIUS + rOff;\n return svg`\n <g transform=\"rotate(${northArcAngle}) translate(0, ${-radius})\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M-17.8457 24.984 0 0 17.8458 24.984C11.9868 24.3338 6.0324 24 0 24-6.0323 24-11.9867 24.3338-17.8457 24.984Z\"\n fill=\"var(--instrument-frame-tertiary-color)\"/>\n </g>\n `;\n }\n\n // ---------------------------------------------------------------------------\n // Priority & advice helpers\n // ---------------------------------------------------------------------------\n\n private _angleInRange(value: number, min: number, max: number): boolean {\n const v = normalizeAngle(value);\n const start = normalizeAngle(min);\n const end = normalizeAngle(max);\n return start <= end ? v >= start && v <= end : v >= start || v <= end;\n }\n\n private _buildAdvices(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state = this._angleInRange(this.heading, minAngle, maxAngle)\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {\n minAngle: this._mapAngle(minAngle),\n maxAngle: this._mapAngle(maxAngle),\n type,\n state,\n };\n });\n }\n\n private get _rotEndAngle(): number {\n const maxVal = this.rotMaxValue || 1;\n const barCompassDeg = (this.rotationsPerMinute / maxVal) * ARC_HALF_EXTENT;\n return this._mapAngle(this.heading + barCompassDeg);\n }\n\n private priorityFor(element: CompassSectorPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n // ---------------------------------------------------------------------------\n // Render\n // ---------------------------------------------------------------------------\n\n override render() {\n const rotation = -this.heading;\n const viewBox = this._cachedViewBox;\n const rOff = this._radiusOffset;\n\n const mappedCOG = this._mapAngle(this.courseOverGround);\n const mappedSetpoint =\n this.headingSetpoint != null\n ? this._mapAngle(this.headingSetpoint)\n : undefined;\n const mappedNewSetpoint =\n this.newHeadingSetpoint != null\n ? this._mapAngle(this.newHeadingSetpoint)\n : undefined;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .padding=${PADDING}\n .advices=${this._cachedAdvices}\n .tickmarks=${this._cachedTickmarks}\n .tickmarkStyle=${TickmarkStyle.regular}\n .tickmarksInside=${this.tickmarksInside}\n .state=${this.state}\n .watchCircleType=${WATCH_TYPE}\n .northArrow=${false}\n .areas=${this._cachedAreas}\n .arcFrame=${this._cachedArcFrame}\n .zoomToFitArc=${this.zoomToFitArc}\n .tickFadeAngle=${this._arcHalfExtent * 0.2}\n .rotation=${rotation}\n .angleSetpoint=${mappedSetpoint}\n .newAngleSetpoint=${mappedNewSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading}\n .rotEndAngle=${this._rotEndAngle}\n .rotPriority=${this.priorityFor(CompassSectorPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\" transform=\"rotate(${rotation})\">\n ${this._renderNorthArrow(rOff)}\n ${arrow(\n ArrowStyle.HDG,\n this.heading,\n this.priorityFor(CompassSectorPriorityElement.hdg),\n rOff\n )}\n ${arrow(\n ArrowStyle.COG,\n mappedCOG,\n this.priorityFor(CompassSectorPriorityElement.cog),\n rOff\n )}\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass-sector': ObcCompassSector;\n }\n}\n"],"names":["CompassSectorPriorityElement"],"mappings":"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"}
@@ -42,6 +42,7 @@ export declare class ObcRateOfTurn extends LitElement {
42
42
  barEndAngle: number;
43
43
  watchCircleType: WatchCircleType;
44
44
  rotPortStarboard: boolean;
45
+ rotAtZeroDeadband: number;
45
46
  static styles: import('lit').CSSResult;
46
47
  render(): import('lit-html').TemplateResult<1>;
47
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rate-of-turn.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAE1C,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EAAC,eAAe,EAAE,OAAO,EAAE,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAErC,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,aAAc,SAAQ,UAAU;IACjB,kBAAkB,EAAE,MAAM,CAAK;IAE/B,OAAO,EAAE,OAAO,CAAgB;IAChC,WAAW,EAAE,WAAW,CAAqB;IAC7C,QAAQ,EAAE,QAAQ,CAAoB;IACtC,aAAa,EAAE,MAAM,CAAK;IAC1B,WAAW,EAAE,MAAM,CAAM;IACzB,eAAe,EAAE,eAAe,CACjC;IACE,gBAAgB,EAAE,OAAO,CAAS;IAE7D,OAAgB,MAAM,0BAkBpB;IAEO,MAAM;CAchB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,aAAa,CAAC;KACnC;CACF"}
1
+ {"version":3,"file":"rate-of-turn.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAY,MAAM,KAAK,CAAC;AAE1C,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EAAC,eAAe,EAAE,OAAO,EAAE,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAGxE,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAErC,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBACa,aAAc,SAAQ,UAAU;IACjB,kBAAkB,EAAE,MAAM,CAAK;IAE/B,OAAO,EAAE,OAAO,CAAgB;IAChC,WAAW,EAAE,WAAW,CAAqB;IAC7C,QAAQ,EAAE,QAAQ,CAAoB;IACtC,aAAa,EAAE,MAAM,CAAK;IAC1B,WAAW,EAAE,MAAM,CAAM;IACzB,eAAe,EAAE,eAAe,CACjC;IACE,gBAAgB,EAAE,OAAO,CAAS;IACnC,iBAAiB,EAAE,MAAM,CAAyB;IAE5E,OAAgB,MAAM,0BAkBpB;IAEO,MAAM;CAehB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,aAAa,CAAC;KACnC;CACF"}
@@ -1,9 +1,9 @@
1
1
  import { css, LitElement, html } from "lit";
2
2
  import { property } from "lit/decorators.js";
3
3
  import { WatchCircleType } from "../watch/watch.js";
4
+ import { RotType, RotPosition, ROT_ZERO_DEADBAND_DEG } from "./rot-renderer.js";
4
5
  import { customElement } from "../../decorator.js";
5
6
  import { Priority } from "../types.js";
6
- import { RotType, RotPosition } from "./rot-renderer.js";
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
9
  var __decorateClass = (decorators, target, key, kind) => {
@@ -25,6 +25,7 @@ let ObcRateOfTurn = class extends LitElement {
25
25
  this.barEndAngle = 30;
26
26
  this.watchCircleType = WatchCircleType.single;
27
27
  this.rotPortStarboard = false;
28
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_DEG;
28
29
  }
29
30
  render() {
30
31
  return html`<div class="container">
@@ -37,6 +38,7 @@ let ObcRateOfTurn = class extends LitElement {
37
38
  .rotEndAngle=${this.barEndAngle}
38
39
  .rotationsPerMinute=${this.rotationsPerMinute}
39
40
  .rotPortStarboard=${this.rotPortStarboard}
41
+ .rotAtZeroDeadband=${this.rotAtZeroDeadband}
40
42
  ></obc-watch>
41
43
  </div>`;
42
44
  }
@@ -84,6 +86,9 @@ __decorateClass([
84
86
  __decorateClass([
85
87
  property({ type: Boolean })
86
88
  ], ObcRateOfTurn.prototype, "rotPortStarboard", 2);
89
+ __decorateClass([
90
+ property({ type: Number })
91
+ ], ObcRateOfTurn.prototype, "rotAtZeroDeadband", 2);
87
92
  ObcRateOfTurn = __decorateClass([
88
93
  customElement("obc-rate-of-turn")
89
94
  ], ObcRateOfTurn);
@@ -1 +1 @@
1
- {"version":3,"file":"rate-of-turn.js","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.ts"],"sourcesContent":["import {LitElement, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {WatchCircleType, RotType, RotPosition} from '../watch/watch.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\n\nexport {RotType, RotPosition};\n\n/**\n * `<obc-rate-of-turn>` — Standalone rate-of-turn indicator rendered on a circular watch face.\n *\n * Wraps `<obc-watch>` to display a spinning-dot or arc-bar ROT visualization\n * without any additional instrument overlays. Useful for isolating the ROT\n * indicator in layouts where heading/compass elements are handled separately.\n *\n * ## Features\n *\n * - **Dot mode** (`rotType=\"dots\"`): Five evenly-spaced dots spin at the\n * configured `rotationsPerMinute`.\n * - **Bar mode** (`rotType=\"bar\"`): A banana-shaped arc from `barStartAngle`\n * to `barEndAngle` with clipped spinning dots inside.\n * - **Track position**: Place the indicator on the outer scale ring\n * (`rotPosition=\"scale\"`) or the inner circle\n * (`rotPosition=\"innerCircle\"`).\n * - **Color priority**: Uses `priority` to select regular or enhanced color\n * palette.\n *\n * ## Usage Guidelines\n *\n * - Set `rotationsPerMinute` to the current sensor value; sign controls\n * spin direction (positive = clockwise).\n * - In bar mode, `barStartAngle` and `barEndAngle` define the static arc\n * span (0° = 12 o'clock, clockwise).\n * - Change `watchCircleType` to match the surrounding instrument ring style\n * (e.g. `triple` for compass contexts).\n *\n * @element obc-rate-of-turn\n */\n@customElement('obc-rate-of-turn')\nexport class ObcRateOfTurn extends LitElement {\n @property({type: Number}) rotationsPerMinute: number = 1;\n\n @property({type: String}) rotType: RotType = RotType.dots;\n @property({type: String}) rotPosition: RotPosition = RotPosition.scale;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Number}) barStartAngle: number = 0;\n @property({type: Number}) barEndAngle: number = 30;\n @property({type: String}) watchCircleType: WatchCircleType =\n WatchCircleType.single;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\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\n override render() {\n return html`<div class=\"container\">\n <obc-watch\n .watchCircleType=${this.watchCircleType}\n .priority=${this.priority}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.barStartAngle}\n .rotEndAngle=${this.barEndAngle}\n .rotationsPerMinute=${this.rotationsPerMinute}\n .rotPortStarboard=${this.rotPortStarboard}\n ></obc-watch>\n </div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-rate-of-turn': ObcRateOfTurn;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAwCO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,qBAA6B;AAE7B,SAAA,UAAmB,QAAQ;AAC3B,SAAA,cAA2B,YAAY;AACvC,SAAA,WAAqB,SAAS;AAC9B,SAAA,gBAAwB;AACxB,SAAA,cAAsB;AACtB,SAAA,kBACxB,gBAAgB;AACS,SAAA,mBAA4B;AAAA,EAAA;AAAA,EAsB9C,SAAS;AAChB,WAAO;AAAA;AAAA,2BAEgB,KAAK,eAAe;AAAA,oBAC3B,KAAK,QAAQ;AAAA,mBACd,KAAK,OAAO;AAAA,uBACR,KAAK,WAAW;AAAA,yBACd,KAAK,aAAa;AAAA,uBACpB,KAAK,WAAW;AAAA,8BACT,KAAK,kBAAkB;AAAA,4BACzB,KAAK,gBAAgB;AAAA;AAAA;AAAA,EAG/C;AACF;AA9Ca,cAYK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAXC,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,cACe,WAAA,sBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,cAGe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,cAIe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,cAKe,WAAA,YAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,cAMe,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,cAOe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GARb,cAQe,WAAA,mBAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAVd,cAUgB,WAAA,oBAAA,CAAA;AAVhB,gBAAN,gBAAA;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB,aAAA;"}
1
+ {"version":3,"file":"rate-of-turn.js","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.ts"],"sourcesContent":["import {LitElement, css, html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {WatchCircleType, RotType, RotPosition} from '../watch/watch.js';\nimport {ROT_ZERO_DEADBAND_DEG} from './rot-renderer.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\n\nexport {RotType, RotPosition};\n\n/**\n * `<obc-rate-of-turn>` — Standalone rate-of-turn indicator rendered on a circular watch face.\n *\n * Wraps `<obc-watch>` to display a spinning-dot or arc-bar ROT visualization\n * without any additional instrument overlays. Useful for isolating the ROT\n * indicator in layouts where heading/compass elements are handled separately.\n *\n * ## Features\n *\n * - **Dot mode** (`rotType=\"dots\"`): Five evenly-spaced dots spin at the\n * configured `rotationsPerMinute`.\n * - **Bar mode** (`rotType=\"bar\"`): A banana-shaped arc from `barStartAngle`\n * to `barEndAngle` with clipped spinning dots inside.\n * - **Track position**: Place the indicator on the outer scale ring\n * (`rotPosition=\"scale\"`) or the inner circle\n * (`rotPosition=\"innerCircle\"`).\n * - **Color priority**: Uses `priority` to select regular or enhanced color\n * palette.\n *\n * ## Usage Guidelines\n *\n * - Set `rotationsPerMinute` to the current sensor value; sign controls\n * spin direction (positive = clockwise).\n * - In bar mode, `barStartAngle` and `barEndAngle` define the static arc\n * span (0° = 12 o'clock, clockwise).\n * - Change `watchCircleType` to match the surrounding instrument ring style\n * (e.g. `triple` for compass contexts).\n *\n * @element obc-rate-of-turn\n */\n@customElement('obc-rate-of-turn')\nexport class ObcRateOfTurn extends LitElement {\n @property({type: Number}) rotationsPerMinute: number = 1;\n\n @property({type: String}) rotType: RotType = RotType.dots;\n @property({type: String}) rotPosition: RotPosition = RotPosition.scale;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Number}) barStartAngle: number = 0;\n @property({type: Number}) barEndAngle: number = 30;\n @property({type: String}) watchCircleType: WatchCircleType =\n WatchCircleType.single;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\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\n override render() {\n return html`<div class=\"container\">\n <obc-watch\n .watchCircleType=${this.watchCircleType}\n .priority=${this.priority}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.barStartAngle}\n .rotEndAngle=${this.barEndAngle}\n .rotationsPerMinute=${this.rotationsPerMinute}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband}\n ></obc-watch>\n </div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-rate-of-turn': ObcRateOfTurn;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAyCO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,qBAA6B;AAE7B,SAAA,UAAmB,QAAQ;AAC3B,SAAA,cAA2B,YAAY;AACvC,SAAA,WAAqB,SAAS;AAC9B,SAAA,gBAAwB;AACxB,SAAA,cAAsB;AACtB,SAAA,kBACxB,gBAAgB;AACS,SAAA,mBAA4B;AAC7B,SAAA,oBAA4B;AAAA,EAAA;AAAA,EAsB7C,SAAS;AAChB,WAAO;AAAA;AAAA,2BAEgB,KAAK,eAAe;AAAA,oBAC3B,KAAK,QAAQ;AAAA,mBACd,KAAK,OAAO;AAAA,uBACR,KAAK,WAAW;AAAA,yBACd,KAAK,aAAa;AAAA,uBACpB,KAAK,WAAW;AAAA,8BACT,KAAK,kBAAkB;AAAA,4BACzB,KAAK,gBAAgB;AAAA,6BACpB,KAAK,iBAAiB;AAAA;AAAA;AAAA,EAGjD;AACF;AAhDa,cAaK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAZC,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,cACe,WAAA,sBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,cAGe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,cAIe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,cAKe,WAAA,YAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,cAMe,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,cAOe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GARb,cAQe,WAAA,mBAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAVd,cAUgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAXb,cAWe,WAAA,qBAAA,CAAA;AAXf,gBAAN,gBAAA;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB,aAAA;"}
@@ -158,6 +158,7 @@ export declare class ObcWatch extends LitElement {
158
158
  rotEndAngle: number;
159
159
  rotPriority: Priority | undefined;
160
160
  rotPortStarboard: boolean;
161
+ rotAtZeroDeadband: number;
161
162
  set rotationsPerMinute(value: number);
162
163
  get rotationsPerMinute(): number;
163
164
  private _rotationsPerMinute;
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import compentStyle from "./watch.css.js";
8
8
  import { ResizeController } from "@lit-labs/observers/resize-controller.js";
9
9
  import { renderAdvice, adviceMask } from "./advice.js";
10
10
  import { TickmarkStyle, tickmark } from "./tickmark.js";
11
- import { RotPosition, RotType, shortestAngularDeltaDeg, rotBarThresholdAngle, ROT_ZERO_DEADBAND_DEG, renderRotZeroPill, renderRotBarStatic, renderRotBarDots, renderRotDots } from "../rate-of-turn/rot-renderer.js";
11
+ import { RotPosition, ROT_ZERO_DEADBAND_DEG, RotType, shortestAngularDeltaDeg, rotBarThresholdAngle, renderRotZeroPill, renderRotBarStatic, renderRotBarDots, renderRotDots } from "../rate-of-turn/rot-renderer.js";
12
12
  import { disposeRotController, RateOfTurnController } from "../rate-of-turn/rate-of-turn.controller.js";
13
13
  import { getLabelPositions, renderLabels, renderNorthArrow } from "./label.js";
14
14
  import { VesselImageSize, vesselImages } from "./vessel.js";
@@ -95,6 +95,7 @@ let ObcWatch = class extends LitElement {
95
95
  this.rotStartAngle = 0;
96
96
  this.rotEndAngle = 0;
97
97
  this.rotPortStarboard = false;
98
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_DEG;
98
99
  this._rotationsPerMinute = 0;
99
100
  this._resizeController = new ResizeController(this, {});
100
101
  this._rOff = 0;
@@ -589,7 +590,8 @@ let ObcWatch = class extends LitElement {
589
590
  this.rotEndAngle
590
591
  );
591
592
  const threshold = rotBarThresholdAngle(this.rotPosition, rOff);
592
- if (angularDelta < ROT_ZERO_DEADBAND_DEG) {
593
+ const zeroDb = Number.isFinite(this.rotAtZeroDeadband) ? this.rotAtZeroDeadband : ROT_ZERO_DEADBAND_DEG;
594
+ if (angularDelta < Math.max(zeroDb, threshold)) {
593
595
  return renderRotZeroPill(
594
596
  barBgColor,
595
597
  this.rotStartAngle,
@@ -597,9 +599,6 @@ let ObcWatch = class extends LitElement {
597
599
  rOff
598
600
  );
599
601
  }
600
- if (angularDelta < threshold) {
601
- return nothing;
602
- }
603
602
  return svg`
604
603
  ${renderRotBarStatic({
605
604
  startAngle: this.rotStartAngle,
@@ -886,6 +885,9 @@ __decorateClass([
886
885
  __decorateClass([
887
886
  property({ type: Boolean })
888
887
  ], ObcWatch.prototype, "rotPortStarboard", 2);
888
+ __decorateClass([
889
+ property({ type: Number })
890
+ ], ObcWatch.prototype, "rotAtZeroDeadband", 2);
889
891
  __decorateClass([
890
892
  property({ type: Number })
891
893
  ], ObcWatch.prototype, "rotationsPerMinute", 1);
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sources":["../../../src/navigation-instruments/watch/watch.ts"],"sourcesContent":["import {\n LitElement,\n PropertyValues,\n SVGTemplateResult,\n html,\n nothing,\n svg,\n unsafeCSS,\n} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {circle} from '../../svghelpers/index.js';\nimport {roundedArch} from '../../svghelpers/roundedArch.js';\nimport {\n cssSafeAngle,\n deriveRadialSetpointConfig,\n drawSetpointMarker,\n getSetpointAnimationDurationMs,\n getSetpointOutwardOffset,\n RADIAL_SETPOINT_RADIUS,\n SetpointVisualState,\n SETPOINT_ANIMATION_CSS_VAR,\n SETPOINT_ANIMATION_DURATION_DEFAULT,\n} from '../../svghelpers/setpoint.js';\nimport {InstrumentState, Priority} from '../types.js';\nimport compentStyle from './watch.css?inline';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {adviceMask, AngleAdviceRaw, renderAdvice} from './advice.js';\nimport {Tickmark, TickmarkStyle, tickmark} from './tickmark.js';\nexport {TickmarkStyle};\nimport {\n RotType,\n RotPosition,\n renderRotDots,\n renderRotBarStatic,\n renderRotBarDots,\n shortestAngularDeltaDeg,\n renderRotZeroPill,\n rotBarThresholdAngle,\n ROT_ZERO_DEADBAND_DEG,\n} from '../rate-of-turn/rot-renderer.js';\nexport {RotType, RotPosition};\nimport {\n RateOfTurnController,\n disposeRotController,\n} from '../rate-of-turn/rate-of-turn.controller.js';\nimport {\n renderLabels,\n renderNorthArrow,\n getLabelPositions,\n LabelPosition,\n} from './label.js';\nimport {VesselImage, VesselImageSize, vesselImages} from './vessel.js';\nimport {renderCurrent, renderWind} from './environment.js';\nimport {customElement} from '../../decorator.js';\nimport {\n computeZoomToFitArcFrame,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\nexport {VesselImage, VesselImageSize};\n\nexport enum WatchCircleType {\n single = 'single',\n double = 'double',\n doubleThin = 'doubleThin',\n triple = 'triple',\n}\n\nexport interface WatchArea {\n startAngle: number;\n endAngle: number;\n roundOutsideCut: boolean;\n roundInsideCut: boolean;\n}\n\nexport interface WatchBarArea {\n startAngle: number;\n endAngle: number;\n fillColor: string;\n}\n\nexport interface WatchNeedle {\n angle: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport interface WatchVessel {\n size: VesselImageSize;\n transform: string;\n vesselImage: VesselImage;\n}\n\nexport const OUTER_RING_RADIUS = 368 / 2;\nconst RING2_RADIUS = 320 / 2;\nconst RING3_RADIUS = 224 / 2;\nconst RING3B_RADIUS = 272 / 2;\nconst RING4_RADIUS = 176 / 2;\n\nexport function innerRingRadiusFor(type: WatchCircleType): number {\n switch (type) {\n case WatchCircleType.single:\n return RING2_RADIUS;\n case WatchCircleType.double:\n return RING3_RADIUS;\n case WatchCircleType.doubleThin:\n return RING3B_RADIUS;\n case WatchCircleType.triple:\n return RING4_RADIUS;\n default:\n throw new Error(`Unknown WatchCircleType: ${type as string}`);\n }\n}\n\nconst RADIAL_SETPOINT_INWARD_ADJUST = 4;\n\n/**\n * `<obc-watch>` - Core SVG renderer for circular/radial watch-based instruments.\n *\n * This component renders all circular instrument elements including rings, tickmarks,\n * bar areas, needles, advices, setpoints, vessel images, and environmental indicators\n * (wind/current). It serves as the foundation for compass, heading, rudder, speed-gauge,\n * and other radial navigation instruments.\n *\n * ## Setpoint Behavior\n *\n * The setpoint marker visual state is derived from the combination of `atAngleSetpoint`,\n * `angleSetpoint`, and `angleSetpointAtZeroDeadband` properties:\n *\n * - **notEqual**: Value differs from setpoint (triangular marker, offset outward)\n * - **equal**: Value matches setpoint (line marker, sits on ring)\n * - **equalZero**: Value matches setpoint at zero angle (double-line marker, offset outward)\n * - **focus**: User is actively adjusting via `newAngleSetpoint` - shows focus visual state\n *\n * ## newAngleSetpoint Pattern\n *\n * When `newAngleSetpoint` is defined, TWO setpoint markers are rendered:\n * 1. Original marker at `angleSetpoint` - dimmed (0.75 opacity)\n * 2. New marker at `newAngleSetpoint` - focus visual state, full opacity\n *\n * This enables the \"adjustment preview\" UX where users can see both the current\n * and proposed setpoint positions simultaneously.\n *\n * The `RADIAL_SETPOINT_INWARD_ADJUST` constant (4px) fine-tunes radial setpoint positioning\n * to match Figma designs, applied on top of visual state offsets from setpoint.ts.\n *\n * The `colorMode` property allows overriding the derived color mode (enhanced for enhanced priority,\n * regular for other states).\n *\n * ## Setpoint Animation (`animateSetpoint`)\n *\n * When `animateSetpoint` is true and a confirm occurs (`newAngleSetpoint` → `undefined`):\n * - The original setpoint slides to the new position via CSS transition\n * - The departing new-setpoint marker fades out\n * - Angular transitions always take the shortest path via accumulated\n * CSS-safe angles (`cssSafeAngle()`), so even 350° → 10° animates +20°\n *\n * Duration: `var(--setpoint-animation-duration, 300ms)`\n *\n * Internally, `_departingNewAngleSetpoint` captures the departing angle during confirm\n * fade-out and `_animationTimer` auto-clears it after the animation duration.\n * `_setpointCssAngle` tracks the accumulated CSS angle to avoid long-way-around\n * transitions across the 0°/360° boundary.\n *\n * @property {InstrumentState} state - Instrument state (active, loading, off)\n * @property {Priority} priority - Color priority (enhanced = blue palette, regular = gray palette)\n * @property {number|undefined} angleSetpoint - Setpoint angle in degrees (0° = 12 o'clock)\n * @property {number|undefined} newAngleSetpoint - New setpoint being adjusted (focus mode)\n * @property {boolean} atAngleSetpoint - Whether value matches setpoint (within deadband)\n * @property {number} angleSetpointAtZeroDeadband - Deadband for zero detection (default 0.5°)\n * @property {boolean} setpointOverride - Override to derive setpoint color from priority regardless of state\n * @property {RotType|undefined} rotType - ROT visualization type: `'dots'` (spinning dots) or `'bar'` (arc bar with clipped dots). Undefined hides the ROT layer.\n * @property {RotPosition} rotPosition - Track on which ROT elements are placed: `'scale'` (on the outer ring) or `'innerCircle'` (default, inside the inner ring)\n * @property {number} rotStartAngle - Start angle of the ROT bar arc in degrees (0° = 12 o'clock, clockwise). Only used when `rotType` is `'bar'`.\n * @property {number} rotEndAngle - End angle of the ROT bar arc in degrees. The bar is hidden when the difference from `rotStartAngle` is less than 0.1°.\n * @property {Priority|undefined} rotPriority - Override priority for ROT color derivation. When set, ROT colors use this instead of the main `priority`. Useful when the ROT element has independent priority (e.g. compass per-element priority).\n * @property {number} rotationsPerMinute - Spin speed of the ROT dot ring in rotations per minute. Sign controls direction (positive = clockwise).\n * @property {ZoomToFitArcFrame|undefined} arcFrame - Pre-computed zoom-to-fit arc frame. When set, the watch skips its own `computeZoomToFitArcFrame()` call and uses these values directly. Consumer instruments (e.g. rudder, instrument-radial) should compute the frame once and pass it here to avoid redundant computation.\n */\n@customElement('obc-watch')\nexport class ObcWatch extends LitElement {\n private _setpointId = `watch-setpoint-${Math.random().toString(36).slice(2, 9)}`;\n private _newSetpointId = `watch-new-setpoint-${Math.random().toString(36).slice(2, 9)}`;\n\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: String}) watchCircleType: WatchCircleType =\n WatchCircleType.single;\n @property({type: Boolean}) northArrow: boolean = false;\n @property({type: Boolean}) northArrowInside: boolean | undefined;\n @property({type: Number}) angleSetpoint: number | undefined;\n @property({type: Number}) newAngleSetpoint: number | undefined;\n @property({type: Boolean}) atAngleSetpoint: boolean = false;\n @property({type: Number}) angleSetpointAtZeroDeadband: number = 0.5;\n @property({type: Boolean}) setpointOverride: boolean = false;\n @property({type: Boolean}) touching: boolean = false;\n\n @property({type: Boolean}) animateSetpoint: boolean = false;\n\n @state() private _departingNewAngleSetpoint: number | undefined;\n private _animationTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Accumulated CSS-safe angle for the original setpoint marker.\n * Ensures CSS rotate() transitions always take the shortest path,\n * even across the 0°/360° boundary.\n */\n private _setpointCssAngle: number = 0;\n\n /** Whether the setpoint CSS angle has been initialised (to skip transition on first render). */\n private _setpointCssAngleInit = false;\n @property({type: Number}) padding: number | undefined;\n @property({type: Array, attribute: false}) areas: WatchArea[] = [];\n @property({type: Array, attribute: false}) barAreas: WatchBarArea[] = [];\n @property({type: Array, attribute: false}) needles: WatchNeedle[] = [];\n @property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n @property({type: Array, attribute: false}) advices: AngleAdviceRaw[] = [];\n @property({type: Boolean}) crosshairEnabled: boolean = false;\n @property({type: Boolean}) showLabels: boolean = false;\n @property({type: Array, attribute: false}) vessels: WatchVessel[] = [];\n @property({type: Number}) wind: number | null = null;\n @property({type: Number}) windFromDirectionDeg: number | null = null;\n @property({type: Number}) windSymbolRadius: number | null = null;\n @property({type: String}) windColor: string | undefined;\n @property({type: Number}) current: number | null = null;\n @property({type: Number}) currentFromDirectionDeg: number | null = null;\n @property({type: Number}) currentSymbolRadius: number | null = null;\n @property({type: String}) currentColor: string | undefined;\n @property({type: Boolean}) starboardPortIndicator: boolean = false;\n @property({type: Number}) clipTop: number = 0; // in percent of height\n @property({type: Number}) clipBottom: number = 0; // in percent of height\n @property({type: Number}) scaleWindIcon: number = 1;\n @property({type: Number}) rotation: number | undefined;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n @property({attribute: false}) arcFrame: ZoomToFitArcFrame | undefined;\n @property({type: Number}) tickFadeAngle: number = 0;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotStartAngle: number = 0;\n @property({type: Number}) rotEndAngle: number = 0;\n @property({type: String}) rotPriority: Priority | undefined;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number})\n set rotationsPerMinute(value: number) {\n this._rotationsPerMinute = value;\n if (this._rotController) {\n this._rotController.rotationsPerMinute = value;\n }\n }\n get rotationsPerMinute() {\n return this._rotationsPerMinute;\n }\n private _rotationsPerMinute = 0;\n private _rotController?: RateOfTurnController;\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 override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Detect confirm: newAngleSetpoint was defined, now undefined\n if (changed.has('newAngleSetpoint') && this.animateSetpoint) {\n const prev = changed.get('newAngleSetpoint') as number | undefined;\n if (prev !== undefined && this.newAngleSetpoint === undefined) {\n this._departingNewAngleSetpoint = prev;\n clearTimeout(this._animationTimer);\n const duration = getSetpointAnimationDurationMs(this);\n this._animationTimer = setTimeout(() => {\n this._departingNewAngleSetpoint = undefined;\n }, duration);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this._animationTimer);\n this._rotController = disposeRotController(this, this._rotController);\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n const el = this.rotType\n ? this.renderRoot.querySelector('#rot-spinner')\n : null;\n if (!el) {\n this._rotController = disposeRotController(this, this._rotController);\n return;\n }\n if (!this._rotController || this._rotController.el !== el) {\n this._rotController = disposeRotController(this, this._rotController);\n this._rotController = new RateOfTurnController(\n this,\n el,\n this._rotationsPerMinute\n );\n }\n }\n\n private get innerRingRadius(): number {\n return innerRingRadiusFor(this.watchCircleType);\n }\n\n private _rOff = 0;\n\n private watchCircle(): SVGTemplateResult | SVGTemplateResult[] {\n const rings = [];\n if (this.state !== InstrumentState.off) {\n rings.push(svg`\n <circle\n cx=\"0\"\n cy=\"0\"\n r=\"${172 + this._rOff}\"\n stroke=\"var(--instrument-frame-primary-color)\"\n fill=\"none\"\n stroke-width=\"24\"\n />`);\n\n if (this.watchCircleType !== WatchCircleType.single) {\n const r1 = RING2_RADIUS + this._rOff;\n const r2 =\n (this.watchCircleType === WatchCircleType.doubleThin\n ? RING3B_RADIUS\n : RING3_RADIUS) + this._rOff;\n const r = (r1 + r2) / 2;\n const strokeWidth = r1 - r2;\n rings.push(\n svg`\n <circle cx=\"0\" cy=\"0\" r=${r} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=${strokeWidth} fill=\"none\" />\n <circle cx=\"0\" cy=\"0\" r=${r1} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=\"1\" fill=\"none\" vector-effect=\"non-scaling-stroke\" />\n <circle cx=\"0\" cy=\"0\" r=${r2} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=\"1\" fill=\"none\" vector-effect=\"non-scaling-stroke\" />\n `\n );\n }\n if (this.watchCircleType === WatchCircleType.triple) {\n const r1 = RING3_RADIUS + this._rOff;\n const r2 = RING4_RADIUS + this._rOff;\n const r = (r1 + r2) / 2;\n const strokeWidth = r1 - r2;\n rings.push(\n svg`<circle cx=\"0\" cy=\"0\" r=${r} stroke=\"var(--instrument-frame-primary-color)\" stroke-width=${strokeWidth} fill=\"none\" />`\n );\n }\n }\n\n const maskSize = Math.max(200, OUTER_RING_RADIUS + this._rOff + 50);\n let result = rings;\n if (this.areas.length > 0) {\n const areas = this.areas.map((area) => {\n const svgPath = roundedArch({\n startAngle: area.startAngle,\n endAngle: area.endAngle,\n R: OUTER_RING_RADIUS + this._rOff,\n r: this.innerRingRadius + this._rOff,\n roundOutsideCut: area.roundOutsideCut,\n roundInsideCut: area.roundInsideCut,\n });\n return svgPath;\n });\n const mask = svg`<mask id=\"cutMask\">\n <rect x=\"${-maskSize}\" y=\"${-maskSize}\" width=\"${maskSize * 2}\" height=\"${maskSize * 2}\" fill=\"black\" />\n ${areas.map((area) => svg`<path d=${area} fill=\"white\" vector-effect=\"non-scaling-stroke\" stroke=\"white\" stroke-width=\"1\"/>`)}\n </mask>`;\n // clipPath for ROT uses r=0 so dots at any track radius stay visible\n const rotClip = svg`<clipPath id=\"rot-arc-clip\">${this.areas.map(\n (area) =>\n svg`<path d=${roundedArch({\n startAngle: area.startAngle,\n endAngle: area.endAngle,\n R: OUTER_RING_RADIUS + this._rOff + 20,\n r: 0,\n roundOutsideCut: area.roundOutsideCut,\n roundInsideCut: area.roundInsideCut,\n })} />`\n )}</clipPath>`;\n result = [mask, rotClip, svg`<g mask=\"url(#cutMask)\">${rings}</g>`];\n areas.forEach((area) => {\n result.push(\n svg`<path d=${area} fill=\"none\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>`\n );\n });\n } else {\n if (this.state !== InstrumentState.off) {\n result.push(\n circle('outerRing', {\n radius: OUTER_RING_RADIUS + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })\n );\n\n result.push(svg`\n ${circle('innerRing', {\n radius: this.innerRingRadius + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })}\n `);\n } else {\n result.push(svg`\n ${circle('innerRing', {\n radius: OUTER_RING_RADIUS + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })}\n `);\n }\n }\n return result;\n }\n\n private _renderTickFadeDefs(): SVGTemplateResult | typeof nothing {\n if (this.tickFadeAngle <= 0 || this.areas.length === 0) return nothing;\n const area = this.areas[0];\n const arcSpan = area.endAngle - area.startAngle;\n const fade = Math.min(this.tickFadeAngle, arcSpan / 4);\n if (fade < 0.5) return nothing;\n\n const {startAngle, endAngle} = area;\n const R = OUTER_RING_RADIUS + this._rOff + 200;\n const toRad = (deg: number) => (deg * Math.PI) / 180;\n const px = (deg: number) => R * Math.sin(toRad(deg));\n const py = (deg: number) => -R * Math.cos(toRad(deg));\n\n const pieSlice = (a: number, b: number): string => {\n const x1 = px(a),\n y1 = py(a);\n const x2 = px(b),\n y2 = py(b);\n const largeArc = b - a > 180 ? 1 : 0;\n return `M 0 0 L ${x1} ${y1} A ${R} ${R} 0 ${largeArc} 1 ${x2} ${y2} Z`;\n };\n\n const Rm = (OUTER_RING_RADIUS + this.innerRingRadius) / 2 + this._rOff;\n const gx = (deg: number) => Rm * Math.sin(toRad(deg));\n const gy = (deg: number) => -Rm * Math.cos(toRad(deg));\n\n return svg`\n <defs>\n <linearGradient id=\"tickFadeL\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${gx(startAngle)}\" y1=\"${gy(startAngle)}\"\n x2=\"${gx(startAngle + fade)}\" y2=\"${gy(startAngle + fade)}\">\n <stop offset=\"0\" stop-color=\"black\" />\n <stop offset=\"1\" stop-color=\"white\" />\n </linearGradient>\n <linearGradient id=\"tickFadeR\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${gx(endAngle - fade)}\" y1=\"${gy(endAngle - fade)}\"\n x2=\"${gx(endAngle)}\" y2=\"${gy(endAngle)}\">\n <stop offset=\"0\" stop-color=\"white\" />\n <stop offset=\"1\" stop-color=\"black\" />\n </linearGradient>\n <mask id=\"tickFadeMask\" maskUnits=\"userSpaceOnUse\"\n x=\"${-R}\" y=\"${-R}\" width=\"${R * 2}\" height=\"${R * 2}\">\n <path d=\"${pieSlice(startAngle + fade, endAngle - fade)}\" fill=\"white\" />\n <path d=\"${pieSlice(startAngle, startAngle + fade)}\" fill=\"url(#tickFadeL)\" />\n <path d=\"${pieSlice(endAngle - fade, endAngle)}\" fill=\"url(#tickFadeR)\" />\n </mask>\n </defs>\n `;\n }\n\n private renderCrosshair(\n radius: number,\n labelKnockouts?: {\n positions: LabelPosition[];\n rotation: number | undefined;\n scale: number;\n /** Inner ring radius – crosshair is hidden between labelRadius and this value. */\n innerRingRadius: number;\n }\n ): SVGTemplateResult {\n const hasMask = labelKnockouts && labelKnockouts.positions.length > 0;\n\n // Radius at which labels sit (distance from centre).\n // Any position is equally valid — they're all at the same radial distance.\n const labelRadius = hasMask\n ? Math.max(\n ...labelKnockouts!.positions.map((l) =>\n Math.abs(l.x !== 0 ? l.x : l.y)\n )\n )\n : 0;\n // Small extra padding so the crosshair doesn't start/end right at the\n // label edge — use the same visual pad as the letter knockouts.\n const ringGapPad = hasMask ? 3 / labelKnockouts!.scale : 0;\n\n return svg`\n ${\n hasMask\n ? svg`\n <defs>\n <mask\n id=\"crosshair-label-mask\"\n maskUnits=\"userSpaceOnUse\"\n x=\"-${radius}\" y=\"-${radius}\"\n width=\"${radius * 2}\" height=\"${radius * 2}\"\n >\n <rect x=\"-${radius}\" y=\"-${radius}\" width=\"${radius * 2}\" height=\"${radius * 2}\" fill=\"white\"/>\n <!-- Annular ring knockout: hide crosshair between labels and inner ring -->\n <circle cx=\"0\" cy=\"0\" r=\"${labelKnockouts!.innerRingRadius}\" fill=\"black\"/>\n <circle cx=\"0\" cy=\"0\" r=\"${labelRadius - ringGapPad}\" fill=\"white\"/>\n <!-- Per-label rectangular knockouts -->\n ${labelKnockouts!.positions.map((l) => {\n const fontSize = 12 / labelKnockouts!.scale;\n const pad = 3 / labelKnockouts!.scale;\n const size = fontSize + pad * 2;\n return svg`\n <rect\n x=\"${l.x - size / 2}\" y=\"${l.y - size / 2}\"\n width=\"${size}\" height=\"${size}\"\n fill=\"black\"\n transform=\"rotate(${-(labelKnockouts!.rotation ?? 0)})\"\n transform-origin=\"${l.x} ${l.y}\"\n />\n `;\n })}\n </mask>\n </defs>`\n : nothing\n }\n <g mask=${hasMask ? 'url(#crosshair-label-mask)' : nothing}>\n <line\n x1=\"-${radius}\"\n y1=\"0\"\n x2=\"${radius}\"\n y2=\"0\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <line\n x1=\"0\"\n y1=\"-${radius}\"\n x2=\"0\"\n y2=\"${radius}\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n </g>\n `;\n }\n\n private renderBars(): SVGTemplateResult[] | typeof nothing {\n if (this.barAreas.length === 0) {\n return nothing;\n }\n return this.barAreas.map((bar, index) => {\n const startAngle = Math.min(bar.startAngle, bar.endAngle);\n const endAngle = Math.max(bar.startAngle, bar.endAngle);\n const arc = roundedArch({\n r: RING3_RADIUS + this._rOff,\n R: RING2_RADIUS + this._rOff,\n startAngle: startAngle,\n endAngle: endAngle,\n roundInsideCut: false,\n roundOutsideCut: false,\n });\n const barMaskR = RING2_RADIUS + this._rOff + 40;\n // The mask is a sector to cut out the stroke on the start and end of the bar\n const mask = svg`<mask id=\"barMask-${index}\">\n <rect x=\"${-barMaskR}\" y=\"${-barMaskR}\" width=\"${barMaskR * 2}\" height=\"${barMaskR * 2}\" fill=\"black\" />\n <path d=${roundedArch({\n r: 1,\n R: barMaskR,\n startAngle: startAngle,\n endAngle: endAngle,\n roundInsideCut: false,\n roundOutsideCut: false,\n })} fill=\"white\" />\n </mask>`;\n return svg`\n ${mask}\n <g mask=\"url(#cutMask)\">\n <path \n d=${arc} \n fill=${bar.fillColor} \n stroke=${bar.fillColor} \n stroke-width=\"1\" \n vector-effect=\"non-scaling-stroke\" \n mask=\"url(#barMask-${index})\" \n />\n </g>\n `;\n });\n }\n\n private renderNeedles(): SVGTemplateResult[] | typeof nothing {\n if (this.needles.length === 0) {\n return nothing;\n }\n return this.needles.map((needle) => {\n return svg`\n <rect \n transform=\"rotate(${needle.angle})\" \n x=\"-4\" y=\"${-(RING2_RADIUS + this._rOff)}\" width=\"8\" height=\"48\" rx=\"4\" \n fill=${needle.fillColor} \n stroke=${needle.strokeColor}\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n paint-order=\"stroke fill\"\n />\n `;\n });\n }\n\n private getScale({width, height}: {width: number; height: number}): number {\n let clientWidth = this.clientWidth;\n let clientHeight = this.clientHeight;\n if (clientWidth === 0 || clientHeight === 0) {\n const box = this.parentElement?.getBoundingClientRect();\n if (box) {\n clientWidth = box.width;\n clientHeight = box.height;\n }\n }\n const scale = Math.min(clientWidth / width, clientHeight / height);\n if (scale === Infinity || scale < 0) {\n throw new Error('Watch scale is not valid');\n }\n return scale;\n }\n\n private getPadding(): number {\n if (this.padding !== undefined) {\n return this.padding;\n }\n const hasTickmarksWithText =\n this.tickmarks.length > 0 &&\n this.tickmarks.some((t) => t.text !== undefined);\n if (hasTickmarksWithText && !this.tickmarksInside) {\n return 24 * 2.5;\n }\n return 24;\n }\n\n override render() {\n let width: number;\n let height: number;\n let viewBox: string;\n\n if (this.arcFrame) {\n this._rOff = this.arcFrame.radiusOffset;\n width = this.arcFrame.width;\n height = this.arcFrame.height;\n viewBox = this.arcFrame.viewBox;\n } else if (this.zoomToFitArc && this.areas.length > 0) {\n const ext = this.getPadding();\n const targetSize = (176 + ext) * 2;\n const frame = computeZoomToFitArcFrame({\n areas: this.areas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: this.innerRingRadius,\n extension: ext,\n targetSize,\n });\n this._rOff = frame.radiusOffset;\n width = frame.width;\n height = frame.height;\n viewBox = frame.viewBox;\n } else {\n this._rOff = 0;\n width = (176 + this.getPadding()) * 2;\n height = width * (1 - this.clipTop / 100 - this.clipBottom / 100);\n const top = -width / 2 + (width * this.clipTop) / 100;\n viewBox = `-${width / 2} ${top} ${width} ${height}`;\n }\n\n const rOff = this._rOff;\n const scale = this.getScale({width, height});\n const angleSetpoint = this.renderSetpoint();\n const textRadius =\n (this.tickmarksInside ? this.innerRingRadius : OUTER_RING_RADIUS) + rOff;\n const maxDigits = Math.max(\n ...this.tickmarks.map((t) => t.text?.length ?? 0)\n );\n const tickmarks = this.tickmarks.map((t) =>\n tickmark(t.angle, {\n size: t.type,\n style: this.tickmarkStyle,\n scale,\n text: this.showLabels ? undefined : t.text,\n inside: this.tickmarksInside,\n textRadius,\n rotation: this.rotation,\n maxDigits,\n color: t.color,\n radiusOffset: rOff,\n })\n );\n const advices = this.advices\n ? this.advices.map((a) => renderAdvice(a, rOff))\n : nothing;\n\n // Compute label positions once – used for both rendering and crosshair knockout.\n const insideLabels = this.tickmarksInside && this.showLabels;\n const includeNorth = !this.northArrow;\n const labelPositions = this.showLabels\n ? getLabelPositions({\n scale,\n inside: this.tickmarksInside,\n innerRadius: this.innerRingRadius + rOff,\n includeNorth,\n })\n : undefined;\n\n const labels = labelPositions\n ? renderLabels({\n scale,\n rotation: this.rotation,\n inside: this.tickmarksInside,\n innerRadius: this.innerRingRadius + rOff,\n includeNorth,\n })\n : nothing;\n const northArrowEl = this.northArrow\n ? renderNorthArrow({\n scale,\n rotation: this.rotation,\n inside: this.northArrowInside ?? this.tickmarksInside,\n })\n : nothing;\n const wind =\n this.wind != null && this.windFromDirectionDeg != null\n ? svg`<g transform=\"scale(${this.scaleWindIcon})\">${renderWind({\n wind: this.wind,\n fromDirectionDeg: this.windFromDirectionDeg,\n radius: this.windSymbolRadius ?? 192,\n color: this.windColor,\n })}</g>`\n : nothing;\n const current =\n this.current != null && this.currentFromDirectionDeg != null\n ? renderCurrent({\n current: this.current,\n fromDirectionDeg: this.currentFromDirectionDeg,\n radius: this.currentSymbolRadius ?? 192,\n color: this.currentColor,\n })\n : nothing;\n return html`\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=${viewBox}\n style=\"--scale: ${scale}\"\n transform=\"rotate(${this.rotation ?? 0})\"\n >\n ${this.watchCircle()} ${this.renderBars()}\n ${this.crosshairEnabled\n ? this.renderCrosshair(\n OUTER_RING_RADIUS + rOff,\n insideLabels && labelPositions\n ? {\n positions: labelPositions,\n rotation: this.rotation,\n scale,\n innerRingRadius: this.innerRingRadius + rOff,\n }\n : undefined\n )\n : nothing}\n ${northArrowEl} ${this.renderStarboardPortIndicator()} ${current}\n ${this._renderTickFadeDefs()} ${wind}\n ${this.tickFadeAngle > 0 && this.areas.length > 0\n ? svg`<g mask=\"url(#tickFadeMask)\">${tickmarks}</g>`\n : tickmarks}\n ${this.areas.length > 0\n ? svg`<g clip-path=\"url(#rot-arc-clip)\">${this.renderRot()}</g>`\n : this.renderRot()}\n ${advices} ${angleSetpoint}\n ${this.tickFadeAngle > 0 && this.areas.length > 0\n ? svg`<g mask=\"url(#tickFadeMask)\">${labels}</g>`\n : labels}\n ${this.renderVesselImage()} ${this.renderNeedles()}\n </svg>\n `;\n }\n\n private getRotColors(): {\n dotColor: string;\n barBgColor: string;\n } {\n const p = this.rotPriority ?? this.priority;\n const isEnhanced = p === Priority.enhanced;\n\n if (this.rotPortStarboard) {\n // For bar type, derive direction from bar angles (visual direction);\n // for dots, use spinner RPM.\n let direction: number;\n if (this.rotType === RotType.bar) {\n const cwSpan =\n (((this.rotEndAngle - this.rotStartAngle) % 360) + 360) % 360;\n direction = cwSpan <= 180 ? cwSpan : cwSpan - 360;\n } else {\n direction = this._rotationsPerMinute;\n }\n\n if (direction > 0) {\n return {\n dotColor: 'var(--instrument-starboard-secondary-color)',\n barBgColor: 'var(--instrument-starboard-primary-color)',\n };\n }\n if (direction < 0) {\n return {\n dotColor: 'var(--instrument-port-secondary-color)',\n barBgColor: 'var(--instrument-port-primary-color)',\n };\n }\n }\n\n return {\n dotColor: isEnhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)',\n barBgColor: isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)',\n };\n }\n\n private renderRot(): SVGTemplateResult | typeof nothing {\n if (!this.rotType) return nothing;\n\n const {dotColor, barBgColor} = this.getRotColors();\n const rOff = this._rOff;\n\n if (this.rotType === RotType.bar) {\n const angularDelta = shortestAngularDeltaDeg(\n this.rotStartAngle,\n this.rotEndAngle\n );\n const threshold = rotBarThresholdAngle(this.rotPosition, rOff);\n\n if (angularDelta < ROT_ZERO_DEADBAND_DEG) {\n return renderRotZeroPill(\n barBgColor,\n this.rotStartAngle,\n this.rotPosition,\n rOff\n );\n }\n\n if (angularDelta < threshold) {\n return nothing;\n }\n\n return svg`\n ${renderRotBarStatic({\n startAngle: this.rotStartAngle,\n endAngle: this.rotEndAngle,\n barColor: barBgColor,\n position: this.rotPosition,\n maskId: 'rot-bar-mask',\n radiusOffset: rOff,\n })}\n ${svg`<g clip-path=\"url(#rot-bar-mask)\">\n <g id=\"rot-spinner\">\n ${renderRotBarDots(dotColor, this.rotPosition, rOff)}\n </g>\n </g>`}\n `;\n }\n\n const p = this.rotPriority ?? this.priority;\n const isEnhanced = p === Priority.enhanced;\n let dotsColor: string = isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n if (this.rotPortStarboard) {\n if (this._rotationsPerMinute > 0) {\n dotsColor = 'var(--instrument-starboard-secondary-color)';\n } else if (this._rotationsPerMinute < 0) {\n dotsColor = 'var(--instrument-port-secondary-color)';\n }\n }\n return svg`\n <g id=\"rot-spinner\">\n ${renderRotDots(dotsColor, this.rotPosition, rOff)}\n </g>\n `;\n }\n\n private renderSetpoint(): SVGTemplateResult | typeof nothing {\n if (this.angleSetpoint === undefined) {\n return nothing;\n }\n\n const derived = deriveRadialSetpointConfig({\n state: this.state,\n priority: this.priority,\n atSetpoint: this.atAngleSetpoint,\n angleSetpoint: this.angleSetpoint,\n setpointAtZeroDeadband: this.angleSetpointAtZeroDeadband,\n newAngleSetpoint: this.newAngleSetpoint,\n touching: this.touching,\n setpointOverride: this.setpointOverride,\n });\n\n const {visualState, colorMode, disabled, hasNewSetpoint} = derived;\n\n const outwardOffset = getSetpointOutwardOffset(visualState);\n const radius =\n RADIAL_SETPOINT_RADIUS +\n this._rOff +\n outwardOffset -\n RADIAL_SETPOINT_INWARD_ADJUST;\n\n // Render original setpoint marker (dimmed when newAngleSetpoint is active)\n const opacity = hasNewSetpoint ? 0.75 : 1;\n const originalMarker = drawSetpointMarker({\n visualState,\n colorMode,\n disabled,\n id: this._setpointId,\n });\n\n const animate = this.animateSetpoint;\n const hasDeparting = this._departingNewAngleSetpoint !== undefined;\n\n // Compute CSS-safe accumulated angle so transitions always take the short path\n const rawAngle = this.angleSetpoint + 90;\n if (!this._setpointCssAngleInit) {\n // First render: set angle without transition\n this._setpointCssAngle = rawAngle;\n this._setpointCssAngleInit = true;\n } else {\n this._setpointCssAngle = cssSafeAngle(this._setpointCssAngle, rawAngle);\n }\n\n // Use CSS style transform when animating for smooth transition\n const originalSetpoint = animate\n ? svg`\n <g style=\"transform: rotate(${this._setpointCssAngle}deg) translateX(${-radius}px) rotate(270deg); opacity: ${opacity}; transition: transform var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT}) ease-out, opacity var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT}) ease-out;\">\n ${originalMarker}\n </g>\n `\n : svg`\n <g transform=\"rotate(${this.angleSetpoint + 90}) translate(${-radius}, 0) rotate(270)\" opacity=\"${opacity}\">\n ${originalMarker}\n </g>\n `;\n\n // Render newAngleSetpoint in focus state (always on top)\n // OR render departing newAngleSetpoint during confirm fade-out\n if (hasNewSetpoint || hasDeparting) {\n const isActive = hasNewSetpoint;\n const newAngle = isActive\n ? this.newAngleSetpoint!\n : this._departingNewAngleSetpoint!;\n const targetOpacity = isActive ? 1 : 0;\n\n const focusOutwardOffset = getSetpointOutwardOffset(\n SetpointVisualState.focus\n );\n const focusRadius =\n RADIAL_SETPOINT_RADIUS +\n this._rOff +\n focusOutwardOffset -\n RADIAL_SETPOINT_INWARD_ADJUST;\n\n const newMarker = drawSetpointMarker({\n visualState: SetpointVisualState.focus,\n colorMode,\n disabled: false, // newSetpoint is never disabled\n id: this._newSetpointId,\n });\n\n if (animate) {\n const duration = `var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT})`;\n return svg`\n ${originalSetpoint}\n <g style=\"transform: rotate(${newAngle + 90}deg) translateX(${-focusRadius}px) rotate(270deg); opacity: ${targetOpacity}; transition: opacity ${duration} ease-out;\">\n ${newMarker}\n </g>\n `;\n }\n\n return svg`\n ${originalSetpoint}\n <g transform=\"rotate(${newAngle + 90}) translate(${-focusRadius}, 0) rotate(270)\" opacity=\"${targetOpacity}\">\n ${newMarker}\n </g>\n `;\n }\n\n return originalSetpoint;\n }\n\n private renderVesselImage(): SVGTemplateResult[] | typeof nothing {\n if (this.vessels.length === 0) {\n return nothing;\n }\n\n return this.vessels.map((v) => {\n let size;\n switch (v.size) {\n case VesselImageSize.large:\n size = 224;\n break;\n case VesselImageSize.medium:\n size = 160;\n break;\n default:\n size = 100;\n }\n\n const scale = size / 160;\n return svg`<g style=\"transform: ${v.transform} scale(${scale}) translate(-80px, -80px) \">${vesselImages[v.vesselImage]}</g>`;\n });\n }\n\n private renderStarboardPortIndicator(): SVGTemplateResult[] | typeof nothing {\n if (!this.starboardPortIndicator) {\n return nothing;\n }\n return [\n adviceMask(\n 0,\n 180,\n 'var(--instrument-starboard-secondary-color)',\n 'var(--instrument-starboard-secondary-color)'\n ),\n adviceMask(\n 180,\n 360,\n 'var(--instrument-port-secondary-color)',\n 'var(--instrument-port-secondary-color)'\n ),\n ] as SVGTemplateResult[];\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-watch': ObcWatch;\n }\n}\n"],"names":["WatchCircleType"],"mappings":"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"}
1
+ {"version":3,"file":"watch.js","sources":["../../../src/navigation-instruments/watch/watch.ts"],"sourcesContent":["import {\n LitElement,\n PropertyValues,\n SVGTemplateResult,\n html,\n nothing,\n svg,\n unsafeCSS,\n} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {circle} from '../../svghelpers/index.js';\nimport {roundedArch} from '../../svghelpers/roundedArch.js';\nimport {\n cssSafeAngle,\n deriveRadialSetpointConfig,\n drawSetpointMarker,\n getSetpointAnimationDurationMs,\n getSetpointOutwardOffset,\n RADIAL_SETPOINT_RADIUS,\n SetpointVisualState,\n SETPOINT_ANIMATION_CSS_VAR,\n SETPOINT_ANIMATION_DURATION_DEFAULT,\n} from '../../svghelpers/setpoint.js';\nimport {InstrumentState, Priority} from '../types.js';\nimport compentStyle from './watch.css?inline';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {adviceMask, AngleAdviceRaw, renderAdvice} from './advice.js';\nimport {Tickmark, TickmarkStyle, tickmark} from './tickmark.js';\nexport {TickmarkStyle};\nimport {\n RotType,\n RotPosition,\n renderRotDots,\n renderRotBarStatic,\n renderRotBarDots,\n shortestAngularDeltaDeg,\n renderRotZeroPill,\n rotBarThresholdAngle,\n ROT_ZERO_DEADBAND_DEG,\n} from '../rate-of-turn/rot-renderer.js';\nexport {RotType, RotPosition};\nimport {\n RateOfTurnController,\n disposeRotController,\n} from '../rate-of-turn/rate-of-turn.controller.js';\nimport {\n renderLabels,\n renderNorthArrow,\n getLabelPositions,\n LabelPosition,\n} from './label.js';\nimport {VesselImage, VesselImageSize, vesselImages} from './vessel.js';\nimport {renderCurrent, renderWind} from './environment.js';\nimport {customElement} from '../../decorator.js';\nimport {\n computeZoomToFitArcFrame,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\nexport {VesselImage, VesselImageSize};\n\nexport enum WatchCircleType {\n single = 'single',\n double = 'double',\n doubleThin = 'doubleThin',\n triple = 'triple',\n}\n\nexport interface WatchArea {\n startAngle: number;\n endAngle: number;\n roundOutsideCut: boolean;\n roundInsideCut: boolean;\n}\n\nexport interface WatchBarArea {\n startAngle: number;\n endAngle: number;\n fillColor: string;\n}\n\nexport interface WatchNeedle {\n angle: number;\n fillColor: string;\n strokeColor: string;\n}\n\nexport interface WatchVessel {\n size: VesselImageSize;\n transform: string;\n vesselImage: VesselImage;\n}\n\nexport const OUTER_RING_RADIUS = 368 / 2;\nconst RING2_RADIUS = 320 / 2;\nconst RING3_RADIUS = 224 / 2;\nconst RING3B_RADIUS = 272 / 2;\nconst RING4_RADIUS = 176 / 2;\n\nexport function innerRingRadiusFor(type: WatchCircleType): number {\n switch (type) {\n case WatchCircleType.single:\n return RING2_RADIUS;\n case WatchCircleType.double:\n return RING3_RADIUS;\n case WatchCircleType.doubleThin:\n return RING3B_RADIUS;\n case WatchCircleType.triple:\n return RING4_RADIUS;\n default:\n throw new Error(`Unknown WatchCircleType: ${type as string}`);\n }\n}\n\nconst RADIAL_SETPOINT_INWARD_ADJUST = 4;\n\n/**\n * `<obc-watch>` - Core SVG renderer for circular/radial watch-based instruments.\n *\n * This component renders all circular instrument elements including rings, tickmarks,\n * bar areas, needles, advices, setpoints, vessel images, and environmental indicators\n * (wind/current). It serves as the foundation for compass, heading, rudder, speed-gauge,\n * and other radial navigation instruments.\n *\n * ## Setpoint Behavior\n *\n * The setpoint marker visual state is derived from the combination of `atAngleSetpoint`,\n * `angleSetpoint`, and `angleSetpointAtZeroDeadband` properties:\n *\n * - **notEqual**: Value differs from setpoint (triangular marker, offset outward)\n * - **equal**: Value matches setpoint (line marker, sits on ring)\n * - **equalZero**: Value matches setpoint at zero angle (double-line marker, offset outward)\n * - **focus**: User is actively adjusting via `newAngleSetpoint` - shows focus visual state\n *\n * ## newAngleSetpoint Pattern\n *\n * When `newAngleSetpoint` is defined, TWO setpoint markers are rendered:\n * 1. Original marker at `angleSetpoint` - dimmed (0.75 opacity)\n * 2. New marker at `newAngleSetpoint` - focus visual state, full opacity\n *\n * This enables the \"adjustment preview\" UX where users can see both the current\n * and proposed setpoint positions simultaneously.\n *\n * The `RADIAL_SETPOINT_INWARD_ADJUST` constant (4px) fine-tunes radial setpoint positioning\n * to match Figma designs, applied on top of visual state offsets from setpoint.ts.\n *\n * The `colorMode` property allows overriding the derived color mode (enhanced for enhanced priority,\n * regular for other states).\n *\n * ## Setpoint Animation (`animateSetpoint`)\n *\n * When `animateSetpoint` is true and a confirm occurs (`newAngleSetpoint` → `undefined`):\n * - The original setpoint slides to the new position via CSS transition\n * - The departing new-setpoint marker fades out\n * - Angular transitions always take the shortest path via accumulated\n * CSS-safe angles (`cssSafeAngle()`), so even 350° → 10° animates +20°\n *\n * Duration: `var(--setpoint-animation-duration, 300ms)`\n *\n * Internally, `_departingNewAngleSetpoint` captures the departing angle during confirm\n * fade-out and `_animationTimer` auto-clears it after the animation duration.\n * `_setpointCssAngle` tracks the accumulated CSS angle to avoid long-way-around\n * transitions across the 0°/360° boundary.\n *\n * @property {InstrumentState} state - Instrument state (active, loading, off)\n * @property {Priority} priority - Color priority (enhanced = blue palette, regular = gray palette)\n * @property {number|undefined} angleSetpoint - Setpoint angle in degrees (0° = 12 o'clock)\n * @property {number|undefined} newAngleSetpoint - New setpoint being adjusted (focus mode)\n * @property {boolean} atAngleSetpoint - Whether value matches setpoint (within deadband)\n * @property {number} angleSetpointAtZeroDeadband - Deadband for zero detection (default 0.5°)\n * @property {boolean} setpointOverride - Override to derive setpoint color from priority regardless of state\n * @property {RotType|undefined} rotType - ROT visualization type: `'dots'` (spinning dots) or `'bar'` (arc bar with clipped dots). Undefined hides the ROT layer.\n * @property {RotPosition} rotPosition - Track on which ROT elements are placed: `'scale'` (on the outer ring) or `'innerCircle'` (default, inside the inner ring)\n * @property {number} rotStartAngle - Start angle of the ROT bar arc in degrees (0° = 12 o'clock, clockwise). Only used when `rotType` is `'bar'`.\n * @property {number} rotEndAngle - End angle of the ROT bar arc in degrees. The bar is hidden when the difference from `rotStartAngle` is less than 0.1°.\n * @property {Priority|undefined} rotPriority - Override priority for ROT color derivation. When set, ROT colors use this instead of the main `priority`. Useful when the ROT element has independent priority (e.g. compass per-element priority).\n * @property {number} rotationsPerMinute - Spin speed of the ROT dot ring in rotations per minute. Sign controls direction (positive = clockwise).\n * @property {ZoomToFitArcFrame|undefined} arcFrame - Pre-computed zoom-to-fit arc frame. When set, the watch skips its own `computeZoomToFitArcFrame()` call and uses these values directly. Consumer instruments (e.g. rudder, instrument-radial) should compute the frame once and pass it here to avoid redundant computation.\n */\n@customElement('obc-watch')\nexport class ObcWatch extends LitElement {\n private _setpointId = `watch-setpoint-${Math.random().toString(36).slice(2, 9)}`;\n private _newSetpointId = `watch-new-setpoint-${Math.random().toString(36).slice(2, 9)}`;\n\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: String}) watchCircleType: WatchCircleType =\n WatchCircleType.single;\n @property({type: Boolean}) northArrow: boolean = false;\n @property({type: Boolean}) northArrowInside: boolean | undefined;\n @property({type: Number}) angleSetpoint: number | undefined;\n @property({type: Number}) newAngleSetpoint: number | undefined;\n @property({type: Boolean}) atAngleSetpoint: boolean = false;\n @property({type: Number}) angleSetpointAtZeroDeadband: number = 0.5;\n @property({type: Boolean}) setpointOverride: boolean = false;\n @property({type: Boolean}) touching: boolean = false;\n\n @property({type: Boolean}) animateSetpoint: boolean = false;\n\n @state() private _departingNewAngleSetpoint: number | undefined;\n private _animationTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Accumulated CSS-safe angle for the original setpoint marker.\n * Ensures CSS rotate() transitions always take the shortest path,\n * even across the 0°/360° boundary.\n */\n private _setpointCssAngle: number = 0;\n\n /** Whether the setpoint CSS angle has been initialised (to skip transition on first render). */\n private _setpointCssAngleInit = false;\n @property({type: Number}) padding: number | undefined;\n @property({type: Array, attribute: false}) areas: WatchArea[] = [];\n @property({type: Array, attribute: false}) barAreas: WatchBarArea[] = [];\n @property({type: Array, attribute: false}) needles: WatchNeedle[] = [];\n @property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n @property({type: Array, attribute: false}) advices: AngleAdviceRaw[] = [];\n @property({type: Boolean}) crosshairEnabled: boolean = false;\n @property({type: Boolean}) showLabels: boolean = false;\n @property({type: Array, attribute: false}) vessels: WatchVessel[] = [];\n @property({type: Number}) wind: number | null = null;\n @property({type: Number}) windFromDirectionDeg: number | null = null;\n @property({type: Number}) windSymbolRadius: number | null = null;\n @property({type: String}) windColor: string | undefined;\n @property({type: Number}) current: number | null = null;\n @property({type: Number}) currentFromDirectionDeg: number | null = null;\n @property({type: Number}) currentSymbolRadius: number | null = null;\n @property({type: String}) currentColor: string | undefined;\n @property({type: Boolean}) starboardPortIndicator: boolean = false;\n @property({type: Number}) clipTop: number = 0; // in percent of height\n @property({type: Number}) clipBottom: number = 0; // in percent of height\n @property({type: Number}) scaleWindIcon: number = 1;\n @property({type: Number}) rotation: number | undefined;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n @property({attribute: false}) arcFrame: ZoomToFitArcFrame | undefined;\n @property({type: Number}) tickFadeAngle: number = 0;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotStartAngle: number = 0;\n @property({type: Number}) rotEndAngle: number = 0;\n @property({type: String}) rotPriority: Priority | undefined;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\n @property({type: Number})\n set rotationsPerMinute(value: number) {\n this._rotationsPerMinute = value;\n if (this._rotController) {\n this._rotController.rotationsPerMinute = value;\n }\n }\n get rotationsPerMinute() {\n return this._rotationsPerMinute;\n }\n private _rotationsPerMinute = 0;\n private _rotController?: RateOfTurnController;\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 override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Detect confirm: newAngleSetpoint was defined, now undefined\n if (changed.has('newAngleSetpoint') && this.animateSetpoint) {\n const prev = changed.get('newAngleSetpoint') as number | undefined;\n if (prev !== undefined && this.newAngleSetpoint === undefined) {\n this._departingNewAngleSetpoint = prev;\n clearTimeout(this._animationTimer);\n const duration = getSetpointAnimationDurationMs(this);\n this._animationTimer = setTimeout(() => {\n this._departingNewAngleSetpoint = undefined;\n }, duration);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this._animationTimer);\n this._rotController = disposeRotController(this, this._rotController);\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n const el = this.rotType\n ? this.renderRoot.querySelector('#rot-spinner')\n : null;\n if (!el) {\n this._rotController = disposeRotController(this, this._rotController);\n return;\n }\n if (!this._rotController || this._rotController.el !== el) {\n this._rotController = disposeRotController(this, this._rotController);\n this._rotController = new RateOfTurnController(\n this,\n el,\n this._rotationsPerMinute\n );\n }\n }\n\n private get innerRingRadius(): number {\n return innerRingRadiusFor(this.watchCircleType);\n }\n\n private _rOff = 0;\n\n private watchCircle(): SVGTemplateResult | SVGTemplateResult[] {\n const rings = [];\n if (this.state !== InstrumentState.off) {\n rings.push(svg`\n <circle\n cx=\"0\"\n cy=\"0\"\n r=\"${172 + this._rOff}\"\n stroke=\"var(--instrument-frame-primary-color)\"\n fill=\"none\"\n stroke-width=\"24\"\n />`);\n\n if (this.watchCircleType !== WatchCircleType.single) {\n const r1 = RING2_RADIUS + this._rOff;\n const r2 =\n (this.watchCircleType === WatchCircleType.doubleThin\n ? RING3B_RADIUS\n : RING3_RADIUS) + this._rOff;\n const r = (r1 + r2) / 2;\n const strokeWidth = r1 - r2;\n rings.push(\n svg`\n <circle cx=\"0\" cy=\"0\" r=${r} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=${strokeWidth} fill=\"none\" />\n <circle cx=\"0\" cy=\"0\" r=${r1} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=\"1\" fill=\"none\" vector-effect=\"non-scaling-stroke\" />\n <circle cx=\"0\" cy=\"0\" r=${r2} stroke=\"var(--instrument-frame-secondary-color)\" stroke-width=\"1\" fill=\"none\" vector-effect=\"non-scaling-stroke\" />\n `\n );\n }\n if (this.watchCircleType === WatchCircleType.triple) {\n const r1 = RING3_RADIUS + this._rOff;\n const r2 = RING4_RADIUS + this._rOff;\n const r = (r1 + r2) / 2;\n const strokeWidth = r1 - r2;\n rings.push(\n svg`<circle cx=\"0\" cy=\"0\" r=${r} stroke=\"var(--instrument-frame-primary-color)\" stroke-width=${strokeWidth} fill=\"none\" />`\n );\n }\n }\n\n const maskSize = Math.max(200, OUTER_RING_RADIUS + this._rOff + 50);\n let result = rings;\n if (this.areas.length > 0) {\n const areas = this.areas.map((area) => {\n const svgPath = roundedArch({\n startAngle: area.startAngle,\n endAngle: area.endAngle,\n R: OUTER_RING_RADIUS + this._rOff,\n r: this.innerRingRadius + this._rOff,\n roundOutsideCut: area.roundOutsideCut,\n roundInsideCut: area.roundInsideCut,\n });\n return svgPath;\n });\n const mask = svg`<mask id=\"cutMask\">\n <rect x=\"${-maskSize}\" y=\"${-maskSize}\" width=\"${maskSize * 2}\" height=\"${maskSize * 2}\" fill=\"black\" />\n ${areas.map((area) => svg`<path d=${area} fill=\"white\" vector-effect=\"non-scaling-stroke\" stroke=\"white\" stroke-width=\"1\"/>`)}\n </mask>`;\n // clipPath for ROT uses r=0 so dots at any track radius stay visible\n const rotClip = svg`<clipPath id=\"rot-arc-clip\">${this.areas.map(\n (area) =>\n svg`<path d=${roundedArch({\n startAngle: area.startAngle,\n endAngle: area.endAngle,\n R: OUTER_RING_RADIUS + this._rOff + 20,\n r: 0,\n roundOutsideCut: area.roundOutsideCut,\n roundInsideCut: area.roundInsideCut,\n })} />`\n )}</clipPath>`;\n result = [mask, rotClip, svg`<g mask=\"url(#cutMask)\">${rings}</g>`];\n areas.forEach((area) => {\n result.push(\n svg`<path d=${area} fill=\"none\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>`\n );\n });\n } else {\n if (this.state !== InstrumentState.off) {\n result.push(\n circle('outerRing', {\n radius: OUTER_RING_RADIUS + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })\n );\n\n result.push(svg`\n ${circle('innerRing', {\n radius: this.innerRingRadius + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })}\n `);\n } else {\n result.push(svg`\n ${circle('innerRing', {\n radius: OUTER_RING_RADIUS + this._rOff,\n strokeWidth: 1,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'center',\n fillColor: 'none',\n })}\n `);\n }\n }\n return result;\n }\n\n private _renderTickFadeDefs(): SVGTemplateResult | typeof nothing {\n if (this.tickFadeAngle <= 0 || this.areas.length === 0) return nothing;\n const area = this.areas[0];\n const arcSpan = area.endAngle - area.startAngle;\n const fade = Math.min(this.tickFadeAngle, arcSpan / 4);\n if (fade < 0.5) return nothing;\n\n const {startAngle, endAngle} = area;\n const R = OUTER_RING_RADIUS + this._rOff + 200;\n const toRad = (deg: number) => (deg * Math.PI) / 180;\n const px = (deg: number) => R * Math.sin(toRad(deg));\n const py = (deg: number) => -R * Math.cos(toRad(deg));\n\n const pieSlice = (a: number, b: number): string => {\n const x1 = px(a),\n y1 = py(a);\n const x2 = px(b),\n y2 = py(b);\n const largeArc = b - a > 180 ? 1 : 0;\n return `M 0 0 L ${x1} ${y1} A ${R} ${R} 0 ${largeArc} 1 ${x2} ${y2} Z`;\n };\n\n const Rm = (OUTER_RING_RADIUS + this.innerRingRadius) / 2 + this._rOff;\n const gx = (deg: number) => Rm * Math.sin(toRad(deg));\n const gy = (deg: number) => -Rm * Math.cos(toRad(deg));\n\n return svg`\n <defs>\n <linearGradient id=\"tickFadeL\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${gx(startAngle)}\" y1=\"${gy(startAngle)}\"\n x2=\"${gx(startAngle + fade)}\" y2=\"${gy(startAngle + fade)}\">\n <stop offset=\"0\" stop-color=\"black\" />\n <stop offset=\"1\" stop-color=\"white\" />\n </linearGradient>\n <linearGradient id=\"tickFadeR\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${gx(endAngle - fade)}\" y1=\"${gy(endAngle - fade)}\"\n x2=\"${gx(endAngle)}\" y2=\"${gy(endAngle)}\">\n <stop offset=\"0\" stop-color=\"white\" />\n <stop offset=\"1\" stop-color=\"black\" />\n </linearGradient>\n <mask id=\"tickFadeMask\" maskUnits=\"userSpaceOnUse\"\n x=\"${-R}\" y=\"${-R}\" width=\"${R * 2}\" height=\"${R * 2}\">\n <path d=\"${pieSlice(startAngle + fade, endAngle - fade)}\" fill=\"white\" />\n <path d=\"${pieSlice(startAngle, startAngle + fade)}\" fill=\"url(#tickFadeL)\" />\n <path d=\"${pieSlice(endAngle - fade, endAngle)}\" fill=\"url(#tickFadeR)\" />\n </mask>\n </defs>\n `;\n }\n\n private renderCrosshair(\n radius: number,\n labelKnockouts?: {\n positions: LabelPosition[];\n rotation: number | undefined;\n scale: number;\n /** Inner ring radius – crosshair is hidden between labelRadius and this value. */\n innerRingRadius: number;\n }\n ): SVGTemplateResult {\n const hasMask = labelKnockouts && labelKnockouts.positions.length > 0;\n\n // Radius at which labels sit (distance from centre).\n // Any position is equally valid — they're all at the same radial distance.\n const labelRadius = hasMask\n ? Math.max(\n ...labelKnockouts!.positions.map((l) =>\n Math.abs(l.x !== 0 ? l.x : l.y)\n )\n )\n : 0;\n // Small extra padding so the crosshair doesn't start/end right at the\n // label edge — use the same visual pad as the letter knockouts.\n const ringGapPad = hasMask ? 3 / labelKnockouts!.scale : 0;\n\n return svg`\n ${\n hasMask\n ? svg`\n <defs>\n <mask\n id=\"crosshair-label-mask\"\n maskUnits=\"userSpaceOnUse\"\n x=\"-${radius}\" y=\"-${radius}\"\n width=\"${radius * 2}\" height=\"${radius * 2}\"\n >\n <rect x=\"-${radius}\" y=\"-${radius}\" width=\"${radius * 2}\" height=\"${radius * 2}\" fill=\"white\"/>\n <!-- Annular ring knockout: hide crosshair between labels and inner ring -->\n <circle cx=\"0\" cy=\"0\" r=\"${labelKnockouts!.innerRingRadius}\" fill=\"black\"/>\n <circle cx=\"0\" cy=\"0\" r=\"${labelRadius - ringGapPad}\" fill=\"white\"/>\n <!-- Per-label rectangular knockouts -->\n ${labelKnockouts!.positions.map((l) => {\n const fontSize = 12 / labelKnockouts!.scale;\n const pad = 3 / labelKnockouts!.scale;\n const size = fontSize + pad * 2;\n return svg`\n <rect\n x=\"${l.x - size / 2}\" y=\"${l.y - size / 2}\"\n width=\"${size}\" height=\"${size}\"\n fill=\"black\"\n transform=\"rotate(${-(labelKnockouts!.rotation ?? 0)})\"\n transform-origin=\"${l.x} ${l.y}\"\n />\n `;\n })}\n </mask>\n </defs>`\n : nothing\n }\n <g mask=${hasMask ? 'url(#crosshair-label-mask)' : nothing}>\n <line\n x1=\"-${radius}\"\n y1=\"0\"\n x2=\"${radius}\"\n y2=\"0\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n <line\n x1=\"0\"\n y1=\"-${radius}\"\n x2=\"0\"\n y2=\"${radius}\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n </g>\n `;\n }\n\n private renderBars(): SVGTemplateResult[] | typeof nothing {\n if (this.barAreas.length === 0) {\n return nothing;\n }\n return this.barAreas.map((bar, index) => {\n const startAngle = Math.min(bar.startAngle, bar.endAngle);\n const endAngle = Math.max(bar.startAngle, bar.endAngle);\n const arc = roundedArch({\n r: RING3_RADIUS + this._rOff,\n R: RING2_RADIUS + this._rOff,\n startAngle: startAngle,\n endAngle: endAngle,\n roundInsideCut: false,\n roundOutsideCut: false,\n });\n const barMaskR = RING2_RADIUS + this._rOff + 40;\n // The mask is a sector to cut out the stroke on the start and end of the bar\n const mask = svg`<mask id=\"barMask-${index}\">\n <rect x=\"${-barMaskR}\" y=\"${-barMaskR}\" width=\"${barMaskR * 2}\" height=\"${barMaskR * 2}\" fill=\"black\" />\n <path d=${roundedArch({\n r: 1,\n R: barMaskR,\n startAngle: startAngle,\n endAngle: endAngle,\n roundInsideCut: false,\n roundOutsideCut: false,\n })} fill=\"white\" />\n </mask>`;\n return svg`\n ${mask}\n <g mask=\"url(#cutMask)\">\n <path \n d=${arc} \n fill=${bar.fillColor} \n stroke=${bar.fillColor} \n stroke-width=\"1\" \n vector-effect=\"non-scaling-stroke\" \n mask=\"url(#barMask-${index})\" \n />\n </g>\n `;\n });\n }\n\n private renderNeedles(): SVGTemplateResult[] | typeof nothing {\n if (this.needles.length === 0) {\n return nothing;\n }\n return this.needles.map((needle) => {\n return svg`\n <rect \n transform=\"rotate(${needle.angle})\" \n x=\"-4\" y=\"${-(RING2_RADIUS + this._rOff)}\" width=\"8\" height=\"48\" rx=\"4\" \n fill=${needle.fillColor} \n stroke=${needle.strokeColor}\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n paint-order=\"stroke fill\"\n />\n `;\n });\n }\n\n private getScale({width, height}: {width: number; height: number}): number {\n let clientWidth = this.clientWidth;\n let clientHeight = this.clientHeight;\n if (clientWidth === 0 || clientHeight === 0) {\n const box = this.parentElement?.getBoundingClientRect();\n if (box) {\n clientWidth = box.width;\n clientHeight = box.height;\n }\n }\n const scale = Math.min(clientWidth / width, clientHeight / height);\n if (scale === Infinity || scale < 0) {\n throw new Error('Watch scale is not valid');\n }\n return scale;\n }\n\n private getPadding(): number {\n if (this.padding !== undefined) {\n return this.padding;\n }\n const hasTickmarksWithText =\n this.tickmarks.length > 0 &&\n this.tickmarks.some((t) => t.text !== undefined);\n if (hasTickmarksWithText && !this.tickmarksInside) {\n return 24 * 2.5;\n }\n return 24;\n }\n\n override render() {\n let width: number;\n let height: number;\n let viewBox: string;\n\n if (this.arcFrame) {\n this._rOff = this.arcFrame.radiusOffset;\n width = this.arcFrame.width;\n height = this.arcFrame.height;\n viewBox = this.arcFrame.viewBox;\n } else if (this.zoomToFitArc && this.areas.length > 0) {\n const ext = this.getPadding();\n const targetSize = (176 + ext) * 2;\n const frame = computeZoomToFitArcFrame({\n areas: this.areas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: this.innerRingRadius,\n extension: ext,\n targetSize,\n });\n this._rOff = frame.radiusOffset;\n width = frame.width;\n height = frame.height;\n viewBox = frame.viewBox;\n } else {\n this._rOff = 0;\n width = (176 + this.getPadding()) * 2;\n height = width * (1 - this.clipTop / 100 - this.clipBottom / 100);\n const top = -width / 2 + (width * this.clipTop) / 100;\n viewBox = `-${width / 2} ${top} ${width} ${height}`;\n }\n\n const rOff = this._rOff;\n const scale = this.getScale({width, height});\n const angleSetpoint = this.renderSetpoint();\n const textRadius =\n (this.tickmarksInside ? this.innerRingRadius : OUTER_RING_RADIUS) + rOff;\n const maxDigits = Math.max(\n ...this.tickmarks.map((t) => t.text?.length ?? 0)\n );\n const tickmarks = this.tickmarks.map((t) =>\n tickmark(t.angle, {\n size: t.type,\n style: this.tickmarkStyle,\n scale,\n text: this.showLabels ? undefined : t.text,\n inside: this.tickmarksInside,\n textRadius,\n rotation: this.rotation,\n maxDigits,\n color: t.color,\n radiusOffset: rOff,\n })\n );\n const advices = this.advices\n ? this.advices.map((a) => renderAdvice(a, rOff))\n : nothing;\n\n // Compute label positions once – used for both rendering and crosshair knockout.\n const insideLabels = this.tickmarksInside && this.showLabels;\n const includeNorth = !this.northArrow;\n const labelPositions = this.showLabels\n ? getLabelPositions({\n scale,\n inside: this.tickmarksInside,\n innerRadius: this.innerRingRadius + rOff,\n includeNorth,\n })\n : undefined;\n\n const labels = labelPositions\n ? renderLabels({\n scale,\n rotation: this.rotation,\n inside: this.tickmarksInside,\n innerRadius: this.innerRingRadius + rOff,\n includeNorth,\n })\n : nothing;\n const northArrowEl = this.northArrow\n ? renderNorthArrow({\n scale,\n rotation: this.rotation,\n inside: this.northArrowInside ?? this.tickmarksInside,\n })\n : nothing;\n const wind =\n this.wind != null && this.windFromDirectionDeg != null\n ? svg`<g transform=\"scale(${this.scaleWindIcon})\">${renderWind({\n wind: this.wind,\n fromDirectionDeg: this.windFromDirectionDeg,\n radius: this.windSymbolRadius ?? 192,\n color: this.windColor,\n })}</g>`\n : nothing;\n const current =\n this.current != null && this.currentFromDirectionDeg != null\n ? renderCurrent({\n current: this.current,\n fromDirectionDeg: this.currentFromDirectionDeg,\n radius: this.currentSymbolRadius ?? 192,\n color: this.currentColor,\n })\n : nothing;\n return html`\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=${viewBox}\n style=\"--scale: ${scale}\"\n transform=\"rotate(${this.rotation ?? 0})\"\n >\n ${this.watchCircle()} ${this.renderBars()}\n ${this.crosshairEnabled\n ? this.renderCrosshair(\n OUTER_RING_RADIUS + rOff,\n insideLabels && labelPositions\n ? {\n positions: labelPositions,\n rotation: this.rotation,\n scale,\n innerRingRadius: this.innerRingRadius + rOff,\n }\n : undefined\n )\n : nothing}\n ${northArrowEl} ${this.renderStarboardPortIndicator()} ${current}\n ${this._renderTickFadeDefs()} ${wind}\n ${this.tickFadeAngle > 0 && this.areas.length > 0\n ? svg`<g mask=\"url(#tickFadeMask)\">${tickmarks}</g>`\n : tickmarks}\n ${this.areas.length > 0\n ? svg`<g clip-path=\"url(#rot-arc-clip)\">${this.renderRot()}</g>`\n : this.renderRot()}\n ${advices} ${angleSetpoint}\n ${this.tickFadeAngle > 0 && this.areas.length > 0\n ? svg`<g mask=\"url(#tickFadeMask)\">${labels}</g>`\n : labels}\n ${this.renderVesselImage()} ${this.renderNeedles()}\n </svg>\n `;\n }\n\n private getRotColors(): {\n dotColor: string;\n barBgColor: string;\n } {\n const p = this.rotPriority ?? this.priority;\n const isEnhanced = p === Priority.enhanced;\n\n if (this.rotPortStarboard) {\n // For bar type, derive direction from bar angles (visual direction);\n // for dots, use spinner RPM.\n let direction: number;\n if (this.rotType === RotType.bar) {\n const cwSpan =\n (((this.rotEndAngle - this.rotStartAngle) % 360) + 360) % 360;\n direction = cwSpan <= 180 ? cwSpan : cwSpan - 360;\n } else {\n direction = this._rotationsPerMinute;\n }\n\n if (direction > 0) {\n return {\n dotColor: 'var(--instrument-starboard-secondary-color)',\n barBgColor: 'var(--instrument-starboard-primary-color)',\n };\n }\n if (direction < 0) {\n return {\n dotColor: 'var(--instrument-port-secondary-color)',\n barBgColor: 'var(--instrument-port-primary-color)',\n };\n }\n }\n\n return {\n dotColor: isEnhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)',\n barBgColor: isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)',\n };\n }\n\n private renderRot(): SVGTemplateResult | typeof nothing {\n if (!this.rotType) return nothing;\n\n const {dotColor, barBgColor} = this.getRotColors();\n const rOff = this._rOff;\n\n if (this.rotType === RotType.bar) {\n const angularDelta = shortestAngularDeltaDeg(\n this.rotStartAngle,\n this.rotEndAngle\n );\n const threshold = rotBarThresholdAngle(this.rotPosition, rOff);\n const zeroDb = Number.isFinite(this.rotAtZeroDeadband)\n ? this.rotAtZeroDeadband\n : ROT_ZERO_DEADBAND_DEG;\n\n if (angularDelta < Math.max(zeroDb, threshold)) {\n return renderRotZeroPill(\n barBgColor,\n this.rotStartAngle,\n this.rotPosition,\n rOff\n );\n }\n\n return svg`\n ${renderRotBarStatic({\n startAngle: this.rotStartAngle,\n endAngle: this.rotEndAngle,\n barColor: barBgColor,\n position: this.rotPosition,\n maskId: 'rot-bar-mask',\n radiusOffset: rOff,\n })}\n ${svg`<g clip-path=\"url(#rot-bar-mask)\">\n <g id=\"rot-spinner\">\n ${renderRotBarDots(dotColor, this.rotPosition, rOff)}\n </g>\n </g>`}\n `;\n }\n\n const p = this.rotPriority ?? this.priority;\n const isEnhanced = p === Priority.enhanced;\n let dotsColor: string = isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n if (this.rotPortStarboard) {\n if (this._rotationsPerMinute > 0) {\n dotsColor = 'var(--instrument-starboard-secondary-color)';\n } else if (this._rotationsPerMinute < 0) {\n dotsColor = 'var(--instrument-port-secondary-color)';\n }\n }\n return svg`\n <g id=\"rot-spinner\">\n ${renderRotDots(dotsColor, this.rotPosition, rOff)}\n </g>\n `;\n }\n\n private renderSetpoint(): SVGTemplateResult | typeof nothing {\n if (this.angleSetpoint === undefined) {\n return nothing;\n }\n\n const derived = deriveRadialSetpointConfig({\n state: this.state,\n priority: this.priority,\n atSetpoint: this.atAngleSetpoint,\n angleSetpoint: this.angleSetpoint,\n setpointAtZeroDeadband: this.angleSetpointAtZeroDeadband,\n newAngleSetpoint: this.newAngleSetpoint,\n touching: this.touching,\n setpointOverride: this.setpointOverride,\n });\n\n const {visualState, colorMode, disabled, hasNewSetpoint} = derived;\n\n const outwardOffset = getSetpointOutwardOffset(visualState);\n const radius =\n RADIAL_SETPOINT_RADIUS +\n this._rOff +\n outwardOffset -\n RADIAL_SETPOINT_INWARD_ADJUST;\n\n // Render original setpoint marker (dimmed when newAngleSetpoint is active)\n const opacity = hasNewSetpoint ? 0.75 : 1;\n const originalMarker = drawSetpointMarker({\n visualState,\n colorMode,\n disabled,\n id: this._setpointId,\n });\n\n const animate = this.animateSetpoint;\n const hasDeparting = this._departingNewAngleSetpoint !== undefined;\n\n // Compute CSS-safe accumulated angle so transitions always take the short path\n const rawAngle = this.angleSetpoint + 90;\n if (!this._setpointCssAngleInit) {\n // First render: set angle without transition\n this._setpointCssAngle = rawAngle;\n this._setpointCssAngleInit = true;\n } else {\n this._setpointCssAngle = cssSafeAngle(this._setpointCssAngle, rawAngle);\n }\n\n // Use CSS style transform when animating for smooth transition\n const originalSetpoint = animate\n ? svg`\n <g style=\"transform: rotate(${this._setpointCssAngle}deg) translateX(${-radius}px) rotate(270deg); opacity: ${opacity}; transition: transform var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT}) ease-out, opacity var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT}) ease-out;\">\n ${originalMarker}\n </g>\n `\n : svg`\n <g transform=\"rotate(${this.angleSetpoint + 90}) translate(${-radius}, 0) rotate(270)\" opacity=\"${opacity}\">\n ${originalMarker}\n </g>\n `;\n\n // Render newAngleSetpoint in focus state (always on top)\n // OR render departing newAngleSetpoint during confirm fade-out\n if (hasNewSetpoint || hasDeparting) {\n const isActive = hasNewSetpoint;\n const newAngle = isActive\n ? this.newAngleSetpoint!\n : this._departingNewAngleSetpoint!;\n const targetOpacity = isActive ? 1 : 0;\n\n const focusOutwardOffset = getSetpointOutwardOffset(\n SetpointVisualState.focus\n );\n const focusRadius =\n RADIAL_SETPOINT_RADIUS +\n this._rOff +\n focusOutwardOffset -\n RADIAL_SETPOINT_INWARD_ADJUST;\n\n const newMarker = drawSetpointMarker({\n visualState: SetpointVisualState.focus,\n colorMode,\n disabled: false, // newSetpoint is never disabled\n id: this._newSetpointId,\n });\n\n if (animate) {\n const duration = `var(${SETPOINT_ANIMATION_CSS_VAR}, ${SETPOINT_ANIMATION_DURATION_DEFAULT})`;\n return svg`\n ${originalSetpoint}\n <g style=\"transform: rotate(${newAngle + 90}deg) translateX(${-focusRadius}px) rotate(270deg); opacity: ${targetOpacity}; transition: opacity ${duration} ease-out;\">\n ${newMarker}\n </g>\n `;\n }\n\n return svg`\n ${originalSetpoint}\n <g transform=\"rotate(${newAngle + 90}) translate(${-focusRadius}, 0) rotate(270)\" opacity=\"${targetOpacity}\">\n ${newMarker}\n </g>\n `;\n }\n\n return originalSetpoint;\n }\n\n private renderVesselImage(): SVGTemplateResult[] | typeof nothing {\n if (this.vessels.length === 0) {\n return nothing;\n }\n\n return this.vessels.map((v) => {\n let size;\n switch (v.size) {\n case VesselImageSize.large:\n size = 224;\n break;\n case VesselImageSize.medium:\n size = 160;\n break;\n default:\n size = 100;\n }\n\n const scale = size / 160;\n return svg`<g style=\"transform: ${v.transform} scale(${scale}) translate(-80px, -80px) \">${vesselImages[v.vesselImage]}</g>`;\n });\n }\n\n private renderStarboardPortIndicator(): SVGTemplateResult[] | typeof nothing {\n if (!this.starboardPortIndicator) {\n return nothing;\n }\n return [\n adviceMask(\n 0,\n 180,\n 'var(--instrument-starboard-secondary-color)',\n 'var(--instrument-starboard-secondary-color)'\n ),\n adviceMask(\n 180,\n 360,\n 'var(--instrument-port-secondary-color)',\n 'var(--instrument-port-secondary-color)'\n ),\n ] as SVGTemplateResult[];\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-watch': ObcWatch;\n }\n}\n"],"names":["WatchCircleType"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DO,IAAK,oCAAAA,qBAAL;AACLA,mBAAA,QAAA,IAAS;AACTA,mBAAA,QAAA,IAAS;AACTA,mBAAA,YAAA,IAAa;AACbA,mBAAA,QAAA,IAAS;AAJC,SAAAA;AAAA,GAAA,mBAAA,CAAA,CAAA;AAgCL,MAAM,oBAAoB,MAAM;AACvC,MAAM,eAAe,MAAM;AAC3B,MAAM,eAAe,MAAM;AAC3B,MAAM,gBAAgB,MAAM;AAC5B,MAAM,eAAe,MAAM;AAEpB,SAAS,mBAAmB,MAA+B;AAChE,UAAQ,MAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,4BAA4B,IAAc,EAAE;AAAA,EAAA;AAElE;AAEA,MAAM,gCAAgC;AAkE/B,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC,cAAA;AAAA,UAAA,GAAA,SAAA;AACL,SAAQ,cAAc,kBAAkB,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC9E,SAAQ,iBAAiB,sBAAsB,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE3D,SAAA,QAAyB,gBAAgB;AACzC,SAAA,WAAqB,SAAS;AAC9B,SAAA,kBACxB;AACyB,SAAA,aAAsB;AAItB,SAAA,kBAA2B;AAC5B,SAAA,8BAAsC;AACrC,SAAA,mBAA4B;AAC5B,SAAA,WAAoB;AAEpB,SAAA,kBAA2B;AAUtD,SAAQ,oBAA4B;AAGpC,SAAQ,wBAAwB;AAEW,SAAA,QAAqB,CAAA;AACrB,SAAA,WAA2B,CAAA;AAC3B,SAAA,UAAyB,CAAA;AACzB,SAAA,YAAwB,CAAA;AACxC,SAAA,kBAA2B;AAC5B,SAAA,gBACxB,cAAc;AAC2B,SAAA,UAA4B,CAAA;AAC5C,SAAA,mBAA4B;AAC5B,SAAA,aAAsB;AACN,SAAA,UAAyB,CAAA;AAC1C,SAAA,OAAsB;AACtB,SAAA,uBAAsC;AACtC,SAAA,mBAAkC;AAElC,SAAA,UAAyB;AACzB,SAAA,0BAAyC;AACzC,SAAA,sBAAqC;AAEpC,SAAA,yBAAkC;AACnC,SAAA,UAAkB;AAClB,SAAA,aAAqB;AACrB,SAAA,gBAAwB;AAEvB,SAAA,eAAwB;AAEzB,SAAA,gBAAwB;AAGxB,SAAA,cAA2B,YAAY;AACvC,SAAA,gBAAwB;AACxB,SAAA,cAAsB;AAErB,SAAA,mBAA4B;AAC7B,SAAA,oBAA4B;AAWtD,SAAQ,sBAAsB;AAK9B,SAAQ,oBAAoB,IAAI,iBAAiB,MAAM,CAAA,CAAE;AAgDzD,SAAQ,QAAQ;AAAA,EAAA;AAAA,EA9DhB,IAAI,mBAAmB,OAAe;AACpC,SAAK,sBAAsB;AAC3B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,qBAAqB;AAAA,IAC3C;AAAA,EACF;AAAA,EACA,IAAI,qBAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAQS,WAAW,SAA+B;AACjD,UAAM,WAAW,OAAO;AAGxB,QAAI,QAAQ,IAAI,kBAAkB,KAAK,KAAK,iBAAiB;AAC3D,YAAM,OAAO,QAAQ,IAAI,kBAAkB;AAC3C,UAAI,SAAS,UAAa,KAAK,qBAAqB,QAAW;AAC7D,aAAK,6BAA6B;AAClC,qBAAa,KAAK,eAAe;AACjC,cAAM,WAAW,+BAA+B,IAAI;AACpD,aAAK,kBAAkB,WAAW,MAAM;AACtC,eAAK,6BAA6B;AAAA,QACpC,GAAG,QAAQ;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA;AACN,iBAAa,KAAK,eAAe;AACjC,SAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AAAA,EACtE;AAAA,EAES,QAAQ,SAA+B;AAC9C,UAAM,QAAQ,OAAO;AACrB,UAAM,KAAK,KAAK,UACZ,KAAK,WAAW,cAAc,cAAc,IAC5C;AACJ,QAAI,CAAC,IAAI;AACP,WAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AACpE;AAAA,IACF;AACA,QAAI,CAAC,KAAK,kBAAkB,KAAK,eAAe,OAAO,IAAI;AACzD,WAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AACpE,WAAK,iBAAiB,IAAI;AAAA,QACxB;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MAAA;AAAA,IAET;AAAA,EACF;AAAA,EAEA,IAAY,kBAA0B;AACpC,WAAO,mBAAmB,KAAK,eAAe;AAAA,EAChD;AAAA,EAIQ,cAAuD;AAC7D,UAAM,QAAQ,CAAA;AACd,QAAI,KAAK,UAAU,gBAAgB,KAAK;AACtC,YAAM,KAAK;AAAA;AAAA;AAAA;AAAA,eAIF,MAAM,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,WAIpB;AAEL,UAAI,KAAK,oBAAoB,UAAwB;AACnD,cAAM,KAAK,eAAe,KAAK;AAC/B,cAAM,MACH,KAAK,oBAAoB,eACtB,gBACA,gBAAgB,KAAK;AAC3B,cAAM,KAAK,KAAK,MAAM;AACtB,cAAM,cAAc,KAAK;AACzB,cAAM;AAAA,UACJ;AAAA,sCAC4B,CAAC,kEAAkE,WAAW;AAAA,sCAC9E,EAAE;AAAA,sCACF,EAAE;AAAA;AAAA,QAAA;AAAA,MAGlC;AACA,UAAI,KAAK,oBAAoB,UAAwB;AACnD,cAAM,KAAK,eAAe,KAAK;AAC/B,cAAM,KAAK,eAAe,KAAK;AAC/B,cAAM,KAAK,KAAK,MAAM;AACtB,cAAM,cAAc,KAAK;AACzB,cAAM;AAAA,UACJ,8BAA8B,CAAC,gEAAgE,WAAW;AAAA,QAAA;AAAA,MAE9G;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,IAAI,KAAK,oBAAoB,KAAK,QAAQ,EAAE;AAClE,QAAI,SAAS;AACb,QAAI,KAAK,MAAM,SAAS,GAAG;AACzB,YAAM,QAAQ,KAAK,MAAM,IAAI,CAAC,SAAS;AACrC,cAAM,UAAU,YAAY;AAAA,UAC1B,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,GAAG,oBAAoB,KAAK;AAAA,UAC5B,GAAG,KAAK,kBAAkB,KAAK;AAAA,UAC/B,iBAAiB,KAAK;AAAA,UACtB,gBAAgB,KAAK;AAAA,QAAA,CACtB;AACD,eAAO;AAAA,MACT,CAAC;AACD,YAAM,OAAO;AAAA,mBACA,CAAC,QAAQ,QAAQ,CAAC,QAAQ,YAAY,WAAW,CAAC,aAAa,WAAW,CAAC;AAAA,UACpF,MAAM,IAAI,CAAC,SAAS,cAAc,IAAI,oFAAoF,CAAC;AAAA;AAG/H,YAAM,UAAU,kCAAkC,KAAK,MAAM;AAAA,QAC3D,CAAC,SACC,cAAc,YAAY;AAAA,UACxB,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,GAAG,oBAAoB,KAAK,QAAQ;AAAA,UACpC,GAAG;AAAA,UACH,iBAAiB,KAAK;AAAA,UACtB,gBAAgB,KAAK;AAAA,QAAA,CACtB,CAAC;AAAA,MAAA,CACL;AACD,eAAS,CAAC,MAAM,SAAS,8BAA8B,KAAK,MAAM;AAClE,YAAM,QAAQ,CAAC,SAAS;AACtB,eAAO;AAAA,UACL,cAAc,IAAI;AAAA,QAAA;AAAA,MAEtB,CAAC;AAAA,IACH,OAAO;AACL,UAAI,KAAK,UAAU,gBAAgB,KAAK;AACtC,eAAO;AAAA,UACL,OAAO,aAAa;AAAA,YAClB,QAAQ,oBAAoB,KAAK;AAAA,YACjC,aAAa;AAAA,YACb,aAAa;AAAA,YACb,gBAAgB;AAAA,YAChB,WAAW;AAAA,UAAA,CACZ;AAAA,QAAA;AAGH,eAAO,KAAK;AAAA,YACR,OAAO,aAAa;AAAA,UACpB,QAAQ,KAAK,kBAAkB,KAAK;AAAA,UACpC,aAAa;AAAA,UACb,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,WAAW;AAAA,QAAA,CACZ,CAAC;AAAA,SACH;AAAA,MACH,OAAO;AACL,eAAO,KAAK;AAAA,YACR,OAAO,aAAa;AAAA,UACpB,QAAQ,oBAAoB,KAAK;AAAA,UACjC,aAAa;AAAA,UACb,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,WAAW;AAAA,QAAA,CACZ,CAAC;AAAA,SACH;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAA0D;AAChE,QAAI,KAAK,iBAAiB,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AAC/D,UAAM,OAAO,KAAK,MAAM,CAAC;AACzB,UAAM,UAAU,KAAK,WAAW,KAAK;AACrC,UAAM,OAAO,KAAK,IAAI,KAAK,eAAe,UAAU,CAAC;AACrD,QAAI,OAAO,IAAK,QAAO;AAEvB,UAAM,EAAC,YAAY,SAAA,IAAY;AAC/B,UAAM,IAAI,oBAAoB,KAAK,QAAQ;AAC3C,UAAM,QAAQ,CAAC,QAAiB,MAAM,KAAK,KAAM;AACjD,UAAM,KAAK,CAAC,QAAgB,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC;AACnD,UAAM,KAAK,CAAC,QAAgB,CAAC,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC;AAEpD,UAAM,WAAW,CAAC,GAAW,MAAsB;AACjD,YAAM,KAAK,GAAG,CAAC,GACb,KAAK,GAAG,CAAC;AACX,YAAM,KAAK,GAAG,CAAC,GACb,KAAK,GAAG,CAAC;AACX,YAAM,WAAW,IAAI,IAAI,MAAM,IAAI;AACnC,aAAO,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,MAAM,EAAE,IAAI,EAAE;AAAA,IACpE;AAEA,UAAM,MAAM,oBAAoB,KAAK,mBAAmB,IAAI,KAAK;AACjE,UAAM,KAAK,CAAC,QAAgB,KAAK,KAAK,IAAI,MAAM,GAAG,CAAC;AACpD,UAAM,KAAK,CAAC,QAAgB,CAAC,KAAK,KAAK,IAAI,MAAM,GAAG,CAAC;AAErD,WAAO;AAAA;AAAA;AAAA,gBAGK,GAAG,UAAU,CAAC,SAAS,GAAG,UAAU,CAAC;AAAA,gBACrC,GAAG,aAAa,IAAI,CAAC,SAAS,GAAG,aAAa,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKnD,GAAG,WAAW,IAAI,CAAC,SAAS,GAAG,WAAW,IAAI,CAAC;AAAA,gBAC/C,GAAG,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,eAKlC,CAAC,CAAC,QAAQ,CAAC,CAAC,YAAY,IAAI,CAAC,aAAa,IAAI,CAAC;AAAA,qBACzC,SAAS,aAAa,MAAM,WAAW,IAAI,CAAC;AAAA,qBAC5C,SAAS,YAAY,aAAa,IAAI,CAAC;AAAA,qBACvC,SAAS,WAAW,MAAM,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA,EAItD;AAAA,EAEQ,gBACN,QACA,gBAOmB;AACnB,UAAM,UAAU,kBAAkB,eAAe,UAAU,SAAS;AAIpE,UAAM,cAAc,UAChB,KAAK;AAAA,MACH,GAAG,eAAgB,UAAU;AAAA,QAAI,CAAC,MAChC,KAAK,IAAI,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,MAAA;AAAA,IAChC,IAEF;AAGJ,UAAM,aAAa,UAAU,IAAI,eAAgB,QAAQ;AAEzD,WAAO;AAAA,QAEH,UACI;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKM,MAAM,SAAS,MAAM;AAAA,qBAClB,SAAS,CAAC,aAAa,SAAS,CAAC;AAAA;AAAA,wBAE9B,MAAM,SAAS,MAAM,YAAY,SAAS,CAAC,aAAa,SAAS,CAAC;AAAA;AAAA,uCAEnD,eAAgB,eAAe;AAAA,uCAC/B,cAAc,UAAU;AAAA;AAAA,cAEjD,eAAgB,UAAU,IAAI,CAAC,MAAM;AACrC,YAAM,WAAW,KAAK,eAAgB;AACtC,YAAM,MAAM,IAAI,eAAgB;AAChC,YAAM,OAAO,WAAW,MAAM;AAC9B,aAAO;AAAA;AAAA,uBAEE,EAAE,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,OAAO,CAAC;AAAA,2BAChC,IAAI,aAAa,IAAI;AAAA;AAAA,sCAEV,EAAE,eAAgB,YAAY,EAAE;AAAA,sCAChC,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA;AAAA;AAAA,IAGpC,CAAC,CAAC;AAAA;AAAA,mBAGF,OACN;AAAA,gBACU,UAAU,+BAA+B,OAAO;AAAA;AAAA,iBAE/C,MAAM;AAAA;AAAA,gBAEP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAQL,MAAM;AAAA;AAAA,gBAEP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB;AAAA,EAEQ,aAAmD;AACzD,QAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,aAAO;AAAA,IACT;AACA,WAAO,KAAK,SAAS,IAAI,CAAC,KAAK,UAAU;AACvC,YAAM,aAAa,KAAK,IAAI,IAAI,YAAY,IAAI,QAAQ;AACxD,YAAM,WAAW,KAAK,IAAI,IAAI,YAAY,IAAI,QAAQ;AACtD,YAAM,MAAM,YAAY;AAAA,QACtB,GAAG,eAAe,KAAK;AAAA,QACvB,GAAG,eAAe,KAAK;AAAA,QACvB;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,MAAA,CAClB;AACD,YAAM,WAAW,eAAe,KAAK,QAAQ;AAE7C,YAAM,OAAO,wBAAwB,KAAK;AAAA,mBAC7B,CAAC,QAAQ,QAAQ,CAAC,QAAQ,YAAY,WAAW,CAAC,aAAa,WAAW,CAAC;AAAA,kBAC5E,YAAY;AAAA,QACpB,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,MAAA,CAClB,CAAC;AAAA;AAEJ,aAAO;AAAA,UACH,IAAI;AAAA;AAAA;AAAA,cAGA,GAAG;AAAA,iBACA,IAAI,SAAS;AAAA,mBACX,IAAI,SAAS;AAAA;AAAA;AAAA,+BAGD,KAAK;AAAA;AAAA;AAAA;AAAA,IAIhC,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAsD;AAC5D,QAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,aAAO;AAAA,IACT;AACA,WAAO,KAAK,QAAQ,IAAI,CAAC,WAAW;AAClC,aAAO;AAAA;AAAA,8BAEiB,OAAO,KAAK;AAAA,sBACpB,EAAE,eAAe,KAAK,MAAM;AAAA,iBACjC,OAAO,SAAS;AAAA,mBACd,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjC,CAAC;AAAA,EACH;AAAA,EAEQ,SAAS,EAAC,OAAO,UAAkD;AACzE,QAAI,cAAc,KAAK;AACvB,QAAI,eAAe,KAAK;AACxB,QAAI,gBAAgB,KAAK,iBAAiB,GAAG;AAC3C,YAAM,MAAM,KAAK,eAAe,sBAAA;AAChC,UAAI,KAAK;AACP,sBAAc,IAAI;AAClB,uBAAe,IAAI;AAAA,MACrB;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,IAAI,cAAc,OAAO,eAAe,MAAM;AACjE,QAAI,UAAU,YAAY,QAAQ,GAAG;AACnC,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAqB;AAC3B,QAAI,KAAK,YAAY,QAAW;AAC9B,aAAO,KAAK;AAAA,IACd;AACA,UAAM,uBACJ,KAAK,UAAU,SAAS,KACxB,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,MAAS;AACjD,QAAI,wBAAwB,CAAC,KAAK,iBAAiB;AACjD,aAAO,KAAK;AAAA,IACd;AACA,WAAO;AAAA,EACT;AAAA,EAES,SAAS;AAChB,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,KAAK,UAAU;AACjB,WAAK,QAAQ,KAAK,SAAS;AAC3B,cAAQ,KAAK,SAAS;AACtB,eAAS,KAAK,SAAS;AACvB,gBAAU,KAAK,SAAS;AAAA,IAC1B,WAAW,KAAK,gBAAgB,KAAK,MAAM,SAAS,GAAG;AACrD,YAAM,MAAM,KAAK,WAAA;AACjB,YAAM,cAAc,MAAM,OAAO;AACjC,YAAM,QAAQ,yBAAyB;AAAA,QACrC,OAAO,KAAK;AAAA,QACZ,aAAa;AAAA,QACb,aAAa,KAAK;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,MAAA,CACD;AACD,WAAK,QAAQ,MAAM;AACnB,cAAQ,MAAM;AACd,eAAS,MAAM;AACf,gBAAU,MAAM;AAAA,IAClB,OAAO;AACL,WAAK,QAAQ;AACb,eAAS,MAAM,KAAK,WAAA,KAAgB;AACpC,eAAS,SAAS,IAAI,KAAK,UAAU,MAAM,KAAK,aAAa;AAC7D,YAAM,MAAM,CAAC,QAAQ,IAAK,QAAQ,KAAK,UAAW;AAClD,gBAAU,IAAI,QAAQ,CAAC,IAAI,GAAG,IAAI,KAAK,IAAI,MAAM;AAAA,IACnD;AAEA,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,SAAS,EAAC,OAAO,QAAO;AAC3C,UAAM,gBAAgB,KAAK,eAAA;AAC3B,UAAM,cACH,KAAK,kBAAkB,KAAK,kBAAkB,qBAAqB;AACtE,UAAM,YAAY,KAAK;AAAA,MACrB,GAAG,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,UAAU,CAAC;AAAA,IAAA;AAElD,UAAM,YAAY,KAAK,UAAU;AAAA,MAAI,CAAC,MACpC,SAAS,EAAE,OAAO;AAAA,QAChB,MAAM,EAAE;AAAA,QACR,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,MAAM,KAAK,aAAa,SAAY,EAAE;AAAA,QACtC,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,UAAU,KAAK;AAAA,QACf;AAAA,QACA,OAAO,EAAE;AAAA,QACT,cAAc;AAAA,MAAA,CACf;AAAA,IAAA;AAEH,UAAM,UAAU,KAAK,UACjB,KAAK,QAAQ,IAAI,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,IAC7C;AAGJ,UAAM,eAAe,KAAK,mBAAmB,KAAK;AAClD,UAAM,eAAe,CAAC,KAAK;AAC3B,UAAM,iBAAiB,KAAK,aACxB,kBAAkB;AAAA,MAChB;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK,kBAAkB;AAAA,MACpC;AAAA,IAAA,CACD,IACD;AAEJ,UAAM,SAAS,iBACX,aAAa;AAAA,MACX;AAAA,MACA,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK,kBAAkB;AAAA,MACpC;AAAA,IAAA,CACD,IACD;AACJ,UAAM,eAAe,KAAK,aACtB,iBAAiB;AAAA,MACf;AAAA,MACA,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK,oBAAoB,KAAK;AAAA,IAAA,CACvC,IACD;AACJ,UAAM,OACJ,KAAK,QAAQ,QAAQ,KAAK,wBAAwB,OAC9C,0BAA0B,KAAK,aAAa,MAAM,WAAW;AAAA,MAC3D,MAAM,KAAK;AAAA,MACX,kBAAkB,KAAK;AAAA,MACvB,QAAQ,KAAK,oBAAoB;AAAA,MACjC,OAAO,KAAK;AAAA,IAAA,CACb,CAAC,SACF;AACN,UAAM,UACJ,KAAK,WAAW,QAAQ,KAAK,2BAA2B,OACpD,cAAc;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,kBAAkB,KAAK;AAAA,MACvB,QAAQ,KAAK,uBAAuB;AAAA,MACpC,OAAO,KAAK;AAAA,IAAA,CACb,IACD;AACN,WAAO;AAAA;AAAA;AAAA;AAAA,kBAIO,OAAO;AAAA,0BACC,KAAK;AAAA,4BACH,KAAK,YAAY,CAAC;AAAA;AAAA,UAEpC,KAAK,YAAA,CAAa,IAAI,KAAK,YAAY;AAAA,UACvC,KAAK,mBACH,KAAK;AAAA,MACH,oBAAoB;AAAA,MACpB,gBAAgB,iBACZ;AAAA,QACE,WAAW;AAAA,QACX,UAAU,KAAK;AAAA,QACf;AAAA,QACA,iBAAiB,KAAK,kBAAkB;AAAA,MAAA,IAE1C;AAAA,IAAA,IAEN,OAAO;AAAA,UACT,YAAY,IAAI,KAAK,6BAAA,CAA8B,IAAI,OAAO;AAAA,UAC9D,KAAK,qBAAqB,IAAI,IAAI;AAAA,UAClC,KAAK,gBAAgB,KAAK,KAAK,MAAM,SAAS,IAC5C,mCAAmC,SAAS,SAC5C,SAAS;AAAA,UACX,KAAK,MAAM,SAAS,IAClB,wCAAwC,KAAK,UAAA,CAAW,SACxD,KAAK,UAAA,CAAW;AAAA,UAClB,OAAO,IAAI,aAAa;AAAA,UACxB,KAAK,gBAAgB,KAAK,KAAK,MAAM,SAAS,IAC5C,mCAAmC,MAAM,SACzC,MAAM;AAAA,UACR,KAAK,kBAAA,CAAmB,IAAI,KAAK,eAAe;AAAA;AAAA;AAAA,EAGxD;AAAA,EAEQ,eAGN;AACA,UAAM,IAAI,KAAK,eAAe,KAAK;AACnC,UAAM,aAAa,MAAM,SAAS;AAElC,QAAI,KAAK,kBAAkB;AAGzB,UAAI;AACJ,UAAI,KAAK,YAAY,QAAQ,KAAK;AAChC,cAAM,WACD,KAAK,cAAc,KAAK,iBAAiB,MAAO,OAAO;AAC5D,oBAAY,UAAU,MAAM,SAAS,SAAS;AAAA,MAChD,OAAO;AACL,oBAAY,KAAK;AAAA,MACnB;AAEA,UAAI,YAAY,GAAG;AACjB,eAAO;AAAA,UACL,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,MAEhB;AACA,UAAI,YAAY,GAAG;AACjB,eAAO;AAAA,UACL,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,MAEhB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,UAAU,aACN,8CACA;AAAA,MACJ,YAAY,aACR,+CACA;AAAA,IAAA;AAAA,EAER;AAAA,EAEQ,YAAgD;AACtD,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,UAAM,EAAC,UAAU,eAAc,KAAK,aAAA;AACpC,UAAM,OAAO,KAAK;AAElB,QAAI,KAAK,YAAY,QAAQ,KAAK;AAChC,YAAM,eAAe;AAAA,QACnB,KAAK;AAAA,QACL,KAAK;AAAA,MAAA;AAEP,YAAM,YAAY,qBAAqB,KAAK,aAAa,IAAI;AAC7D,YAAM,SAAS,OAAO,SAAS,KAAK,iBAAiB,IACjD,KAAK,oBACL;AAEJ,UAAI,eAAe,KAAK,IAAI,QAAQ,SAAS,GAAG;AAC9C,eAAO;AAAA,UACL;AAAA,UACA,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,QAAA;AAAA,MAEJ;AAEA,aAAO;AAAA,UACH,mBAAmB;AAAA,QACnB,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK;AAAA,QACf,UAAU;AAAA,QACV,UAAU,KAAK;AAAA,QACf,QAAQ;AAAA,QACR,cAAc;AAAA,MAAA,CACf,CAAC;AAAA,UACA;AAAA;AAAA,gBAEM,iBAAiB,UAAU,KAAK,aAAa,IAAI,CAAC;AAAA;AAAA,eAEnD;AAAA;AAAA,IAEX;AAEA,UAAM,IAAI,KAAK,eAAe,KAAK;AACnC,UAAM,aAAa,MAAM,SAAS;AAClC,QAAI,YAAoB,aACpB,+CACA;AACJ,QAAI,KAAK,kBAAkB;AACzB,UAAI,KAAK,sBAAsB,GAAG;AAChC,oBAAY;AAAA,MACd,WAAW,KAAK,sBAAsB,GAAG;AACvC,oBAAY;AAAA,MACd;AAAA,IACF;AACA,WAAO;AAAA;AAAA,UAED,cAAc,WAAW,KAAK,aAAa,IAAI,CAAC;AAAA;AAAA;AAAA,EAGxD;AAAA,EAEQ,iBAAqD;AAC3D,QAAI,KAAK,kBAAkB,QAAW;AACpC,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,2BAA2B;AAAA,MACzC,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,eAAe,KAAK;AAAA,MACpB,wBAAwB,KAAK;AAAA,MAC7B,kBAAkB,KAAK;AAAA,MACvB,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK;AAAA,IAAA,CACxB;AAED,UAAM,EAAC,aAAa,WAAW,UAAU,mBAAkB;AAE3D,UAAM,gBAAgB,yBAAyB,WAAW;AAC1D,UAAM,SACJ,yBACA,KAAK,QACL,gBACA;AAGF,UAAM,UAAU,iBAAiB,OAAO;AACxC,UAAM,iBAAiB,mBAAmB;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,KAAK;AAAA,IAAA,CACV;AAED,UAAM,UAAU,KAAK;AACrB,UAAM,eAAe,KAAK,+BAA+B;AAGzD,UAAM,WAAW,KAAK,gBAAgB;AACtC,QAAI,CAAC,KAAK,uBAAuB;AAE/B,WAAK,oBAAoB;AACzB,WAAK,wBAAwB;AAAA,IAC/B,OAAO;AACL,WAAK,oBAAoB,aAAa,KAAK,mBAAmB,QAAQ;AAAA,IACxE;AAGA,UAAM,mBAAmB,UACrB;AAAA,sCAC8B,KAAK,iBAAiB,mBAAmB,CAAC,MAAM,gCAAgC,OAAO,+BAA+B,0BAA0B,KAAK,mCAAmC,2BAA2B,0BAA0B,KAAK,mCAAmC;AAAA,YAC/S,cAAc;AAAA;AAAA,UAGlB;AAAA,+BACuB,KAAK,gBAAgB,EAAE,eAAe,CAAC,MAAM,8BAA8B,OAAO;AAAA,YACrG,cAAc;AAAA;AAAA;AAMtB,QAAI,kBAAkB,cAAc;AAClC,YAAM,WAAW;AACjB,YAAM,WAAW,WACb,KAAK,mBACL,KAAK;AACT,YAAM,gBAAgB,WAAW,IAAI;AAErC,YAAM,qBAAqB;AAAA,QACzB,oBAAoB;AAAA,MAAA;AAEtB,YAAM,cACJ,yBACA,KAAK,QACL,qBACA;AAEF,YAAM,YAAY,mBAAmB;AAAA,QACnC,aAAa,oBAAoB;AAAA,QACjC;AAAA,QACA,UAAU;AAAA;AAAA,QACV,IAAI,KAAK;AAAA,MAAA,CACV;AAED,UAAI,SAAS;AACX,cAAM,WAAW,OAAO,0BAA0B,KAAK,mCAAmC;AAC1F,eAAO;AAAA,YACH,gBAAgB;AAAA,wCACY,WAAW,EAAE,mBAAmB,CAAC,WAAW,gCAAgC,aAAa,yBAAyB,QAAQ;AAAA,cACpJ,SAAS;AAAA;AAAA;AAAA,MAGjB;AAEA,aAAO;AAAA,UACH,gBAAgB;AAAA,+BACK,WAAW,EAAE,eAAe,CAAC,WAAW,8BAA8B,aAAa;AAAA,YACtG,SAAS;AAAA;AAAA;AAAA,IAGjB;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,oBAA0D;AAChE,QAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,QAAQ,IAAI,CAAC,MAAM;AAC7B,UAAI;AACJ,cAAQ,EAAE,MAAA;AAAA,QACR,KAAK,gBAAgB;AACnB,iBAAO;AACP;AAAA,QACF,KAAK,gBAAgB;AACnB,iBAAO;AACP;AAAA,QACF;AACE,iBAAO;AAAA,MAAA;AAGX,YAAM,QAAQ,OAAO;AACrB,aAAO,2BAA2B,EAAE,SAAS,UAAU,KAAK,+BAA+B,aAAa,EAAE,WAAW,CAAC;AAAA,IACxH,CAAC;AAAA,EACH;AAAA,EAEQ,+BAAqE;AAC3E,QAAI,CAAC,KAAK,wBAAwB;AAChC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAEF;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAGF;AAl2Ba,SAi2BK,SAAS,UAAU,YAAY;AA71BrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,SAIe,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,SAKe,WAAA,YAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,SAMe,WAAA,mBAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GARd,SAQgB,WAAA,cAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GATd,SASgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAVb,SAUe,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAXb,SAWe,WAAA,oBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAZd,SAYgB,WAAA,mBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAbb,SAae,WAAA,+BAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAdd,SAcgB,WAAA,oBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAfd,SAegB,WAAA,YAAA,CAAA;AAEA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAjBd,SAiBgB,WAAA,mBAAA,CAAA;AAEV,gBAAA;AAAA,EAAhB,MAAA;AAAM,GAnBI,SAmBM,WAAA,8BAAA,CAAA;AAYS,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Bb,SA+Be,WAAA,WAAA,CAAA;AACiB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAhC9B,SAgCgC,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAjC9B,SAiCgC,WAAA,YAAA,CAAA;AACA,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAlC9B,SAkCgC,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAnC9B,SAmCgC,WAAA,aAAA,CAAA;AAChB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GApCd,SAoCgB,WAAA,mBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArCb,SAqCe,WAAA,iBAAA,CAAA;AAEiB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAvC9B,SAuCgC,WAAA,WAAA,CAAA;AAChB,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAxCd,SAwCgB,WAAA,oBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAzCd,SAyCgB,WAAA,cAAA,CAAA;AACgB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GA1C9B,SA0CgC,WAAA,WAAA,CAAA;AACjB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Cb,SA2Ce,WAAA,QAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Cb,SA4Ce,WAAA,wBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Cb,SA6Ce,WAAA,oBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Cb,SA8Ce,WAAA,aAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Cb,SA+Ce,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhDb,SAgDe,WAAA,2BAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjDb,SAiDe,WAAA,uBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlDb,SAkDe,WAAA,gBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAnDd,SAmDgB,WAAA,0BAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApDb,SAoDe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GArDb,SAqDe,WAAA,cAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtDb,SAsDe,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvDb,SAuDe,WAAA,YAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAxDd,SAwDgB,WAAA,gBAAA,CAAA;AACG,gBAAA;AAAA,EAA7B,SAAS,EAAC,WAAW,MAAA,CAAM;AAAA,GAzDjB,SAyDmB,WAAA,YAAA,CAAA;AACJ,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA1Db,SA0De,WAAA,iBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Db,SA4De,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Db,SA6De,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Db,SA8De,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA/Db,SA+De,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhEb,SAgEe,WAAA,eAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAjEd,SAiEgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlEb,SAkEe,WAAA,qBAAA,CAAA;AAEtB,gBAAA;AAAA,EADH,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnEb,SAoEP,WAAA,sBAAA,CAAA;AApEO,WAAN,gBAAA;AAAA,EADN,cAAc,WAAW;AAAA,GACb,QAAA;"}
@@ -33,6 +33,7 @@ export declare class ObcWatchFlat extends LitElement {
33
33
  rotDotSpacing: number;
34
34
  rotPriority: Priority;
35
35
  rotPortStarboard: boolean;
36
+ rotAtZeroDeadband: number;
36
37
  set rotationsPerMinute(value: number);
37
38
  get rotationsPerMinute(): number;
38
39
  private _rotationsPerMinute;
@@ -1 +1 @@
1
- {"version":3,"file":"watch-flat.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch-flat/watch-flat.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EAKlB,MAAM,KAAK,CAAC;AAGb,OAAO,EAAC,QAAQ,EAA0B,MAAM,oBAAoB,CAAC;AAErE,OAAO,EAAC,KAAK,EAAC,MAAM,iCAAiC,CAAC;AAEtD,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,OAAO,EACP,iBAAiB,EAQlB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,EAAC,OAAO,EAAE,iBAAiB,EAAC,CAAC;AAEpC,qBACa,YAAa,SAAQ,UAAU;IAChB,KAAK,SAAO;IACZ,MAAM,SAAM;IACZ,OAAO,SAAK;IACZ,QAAQ,SAAK;IACb,eAAe,SAAK;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAM;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAM;IACrB,YAAY,EAAE,iBAAiB,EAAE,CACvE;IACqB,WAAW,SAAyB;IACpC,WAAW,SAAkC;IAC7C,YAAY,SAAK;IAChB,SAAS,UAAS;IAEnB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,CAC9B;IAC1B,6GAA6G;IACnF,SAAS,EAAE,MAAM,CAAK;IAChD,2GAA2G;IACjF,OAAO,EAAE,MAAM,CAAK;IAC9C;;;;;OAKG;IACuB,aAAa,EAAE,MAAM,CAAK;IAC1B,WAAW,EAAE,QAAQ,CAAoB;IACxC,gBAAgB,EAAE,OAAO,CAAS;IAE7D,IACI,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAKnC;IACD,IAAI,kBAAkB,IANQ,MAAM,CAQnC;IAED,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAAC,CAAuB;IAE9C,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IA6DjB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,YAAY;IAsCpB,OAAO,CAAC,SAAS;IA2DR,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA0BtC,oBAAoB,IAAI,IAAI;IAK5B,MAAM;IAsCf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
1
+ {"version":3,"file":"watch-flat.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch-flat/watch-flat.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EAKlB,MAAM,KAAK,CAAC;AAGb,OAAO,EAAC,QAAQ,EAA0B,MAAM,oBAAoB,CAAC;AAErE,OAAO,EAAC,KAAK,EAAC,MAAM,iCAAiC,CAAC;AAEtD,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,OAAO,EACP,iBAAiB,EAQlB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,EAAC,OAAO,EAAE,iBAAiB,EAAC,CAAC;AAEpC,qBACa,YAAa,SAAQ,UAAU;IAChB,KAAK,SAAO;IACZ,MAAM,SAAM;IACZ,OAAO,SAAK;IACZ,QAAQ,SAAK;IACb,eAAe,SAAK;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IACjB,SAAS,EAAE,QAAQ,EAAE,CAAM;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAM;IACrB,YAAY,EAAE,iBAAiB,EAAE,CACvE;IACqB,WAAW,SAAyB;IACpC,WAAW,SAAkC;IAC7C,YAAY,SAAK;IAChB,SAAS,UAAS;IAEnB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,CAC9B;IAC1B,6GAA6G;IACnF,SAAS,EAAE,MAAM,CAAK;IAChD,2GAA2G;IACjF,OAAO,EAAE,MAAM,CAAK;IAC9C;;;;;OAKG;IACuB,aAAa,EAAE,MAAM,CAAK;IAC1B,WAAW,EAAE,QAAQ,CAAoB;IACxC,gBAAgB,EAAE,OAAO,CAAS;IACnC,iBAAiB,EAAE,MAAM,CAAwB;IAE3E,IACI,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAKnC;IACD,IAAI,kBAAkB,IANQ,MAAM,CAQnC;IAED,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAAC,CAAuB;IAE9C,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IA6DjB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,YAAY;IAsCpB,OAAO,CAAC,SAAS;IA0DR,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA0BtC,oBAAoB,IAAI,IAAI;IAK5B,MAAM;IAsCf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
@@ -5,7 +5,7 @@ import { tickmark, TickmarkStyle } from "./tickmark-flat.js";
5
5
  import { rect } from "../../svghelpers/rectangular.js";
6
6
  import { customElement } from "../../decorator.js";
7
7
  import { Priority } from "../types.js";
8
- import { LinearRotPosition, RotType, ROT_ZERO_DEADBAND_PX, renderLinearRotZeroPill, BAR_HALF_THICKNESS, renderLinearRotBarStatic, renderLinearRotBarDots, renderLinearRotDots, LINEAR_DOT_ANGLE_SPACING } from "../rate-of-turn/rot-renderer.js";
8
+ import { LinearRotPosition, ROT_ZERO_DEADBAND_PX, RotType, BAR_HALF_THICKNESS, renderLinearRotZeroPill, renderLinearRotBarStatic, renderLinearRotBarDots, renderLinearRotDots, LINEAR_DOT_ANGLE_SPACING } from "../rate-of-turn/rot-renderer.js";
9
9
  import { disposeRotController, RateOfTurnController } from "../rate-of-turn/rate-of-turn.controller.js";
10
10
  var __defProp = Object.defineProperty;
11
11
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -38,6 +38,7 @@ let ObcWatchFlat = class extends LitElement {
38
38
  this.rotDotSpacing = 0;
39
39
  this.rotPriority = Priority.regular;
40
40
  this.rotPortStarboard = false;
41
+ this.rotAtZeroDeadband = ROT_ZERO_DEADBAND_PX;
41
42
  this._rotationsPerMinute = 0;
42
43
  }
43
44
  set rotationsPerMinute(value) {
@@ -186,12 +187,10 @@ let ObcWatchFlat = class extends LitElement {
186
187
  const canAnimateDots = this.rotDotSpacing > 0;
187
188
  if (this.rotType === RotType.bar) {
188
189
  const span = Math.abs(this.rotEndX - this.rotStartX);
189
- if (span < ROT_ZERO_DEADBAND_PX) {
190
+ const zeroDb = Number.isFinite(this.rotAtZeroDeadband) ? this.rotAtZeroDeadband : ROT_ZERO_DEADBAND_PX;
191
+ if (span < Math.max(zeroDb, BAR_HALF_THICKNESS)) {
190
192
  return renderLinearRotZeroPill(barBgColor, this.rotStartX, trackY);
191
193
  }
192
- if (span < BAR_HALF_THICKNESS) {
193
- return nothing;
194
- }
195
194
  return svg`
196
195
  ${renderLinearRotBarStatic({
197
196
  startX: this.rotStartX,
@@ -344,6 +343,9 @@ __decorateClass([
344
343
  __decorateClass([
345
344
  property({ type: Boolean })
346
345
  ], ObcWatchFlat.prototype, "rotPortStarboard", 2);
346
+ __decorateClass([
347
+ property({ type: Number })
348
+ ], ObcWatchFlat.prototype, "rotAtZeroDeadband", 2);
347
349
  __decorateClass([
348
350
  property({ type: Number })
349
351
  ], ObcWatchFlat.prototype, "rotationsPerMinute", 1);
@@ -1 +1 @@
1
- {"version":3,"file":"watch-flat.js","sources":["../../../src/navigation-instruments/watch-flat/watch-flat.ts"],"sourcesContent":["import {\n LitElement,\n PropertyValues,\n SVGTemplateResult,\n html,\n nothing,\n svg,\n unsafeCSS,\n} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './watch-flat.css?inline';\nimport {Tickmark, TickmarkStyle, tickmark} from './tickmark-flat.js';\nimport {rect} from '../../svghelpers/rectangular.js';\nimport {Label} from '../compass-flat/compass-flat.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\nimport {\n RotType,\n LinearRotPosition,\n renderLinearRotDots,\n renderLinearRotBarStatic,\n renderLinearRotBarDots,\n LINEAR_DOT_ANGLE_SPACING,\n renderLinearRotZeroPill,\n BAR_HALF_THICKNESS,\n ROT_ZERO_DEADBAND_PX,\n} from '../rate-of-turn/rot-renderer.js';\nimport {\n RateOfTurnController,\n disposeRotController,\n} from '../rate-of-turn/rate-of-turn.controller.js';\n\nexport {RotType, LinearRotPosition};\n\n@customElement('obc-watch-flat')\nexport class ObcWatchFlat extends LitElement {\n @property({type: Number}) width = 352;\n @property({type: Number}) height = 72;\n @property({type: Number}) padding = 0;\n @property({type: Number}) rotation = 0;\n @property({type: Number}) tickmarkSpacing = 0;\n @property({type: Number}) angleSetpoint: number | undefined;\n @property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];\n @property({type: Array, attribute: false}) labels: Label[] = [];\n @property({type: Array, attribute: false}) FOVIndicator: SVGTemplateResult[] =\n [];\n @property({type: Number}) trackHeight = (2 / 3) * this.height;\n @property({type: Number}) ticksHeight = this.height - this.trackHeight;\n @property({type: Number}) borderRadius = 8;\n @property({type: Boolean}) bottomBar = false;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: LinearRotPosition =\n LinearRotPosition.track;\n /** Bar start position in SVG user-space x-coordinates (center-origin). Computed by the parent instrument. */\n @property({type: Number}) rotStartX: number = 0;\n /** Bar end position in SVG user-space x-coordinates (center-origin). Computed by the parent instrument. */\n @property({type: Number}) rotEndX: number = 0;\n /**\n * Pixel spacing between adjacent dots in the linear ROT strip.\n * Must be > 0 to enable animation; the default `0` intentionally disables\n * the spinning dots so the parent instrument must supply a meaningful value\n * derived from the current scale (e.g. `LINEAR_DOT_ANGLE_SPACING * translationScale`).\n */\n @property({type: Number}) rotDotSpacing: number = 0;\n @property({type: String}) rotPriority: Priority = Priority.regular;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n\n @property({type: Number})\n set rotationsPerMinute(value: number) {\n this._rotationsPerMinute = value;\n if (this._rotController) {\n this._rotController.rotationsPerMinute = value;\n }\n }\n get rotationsPerMinute() {\n return this._rotationsPerMinute;\n }\n\n private _rotationsPerMinute = 0;\n private _rotController?: RateOfTurnController;\n\n private get totalHeight(): number {\n return this.bottomBar ? this.height + this.ticksHeight : this.height;\n }\n\n private renderClipPath(offsetY: number = 0): SVGTemplateResult {\n return svg`\n <clipPath id=\"frameClipPath${offsetY === 0 ? '' : 'Tickmarks'}\">\n <rect x=\"${-this.width / 2}\" y=\"${-this.totalHeight / 2 + offsetY}\" \n width=\"${this.width}\" height=\"${this.totalHeight}\" \n rx=\"${this.borderRadius}\" />\n </clipPath>\n `;\n }\n\n private renderLabelMask(): SVGTemplateResult {\n return svg`\n <mask id=\"labelMask\">\n <rect x=\"${-this.width / 2}\" y=\"${-70}\" \n width=\"${this.width}\" height=\"${32}\"\n />\n <linearGradient id=\"fadeGradient\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${-this.width / 2}\" y1=\"0\" x2=\"${this.width / 2}\" y2=\"0\">\n <stop offset=\"0%\" style=\"stop-color:black; stop-opacity:1;\" />\n <stop offset=\"10%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"50%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"90%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"100%\" style=\"stop-color:black; stop-opacity:1;\" />\n </linearGradient>\n <rect x=\"${-this.width / 2}\" y=\"${-70}\" \n width=\"${this.width}\" height=\"${32}\"\n fill=\"url(#fadeGradient)\" />\n </mask>\n `;\n }\n\n private renderLabels(scale: number): SVGTemplateResult[] {\n const labels: SVGTemplateResult[] = [];\n\n for (const l of this.labels) {\n labels.push(\n svg`<g transform=\"translate(${-this.rotation * this.tickmarkSpacing}, ${-6 / scale})\">\n <text x=${l.x} y=${l.y} class=\"label\" fill=${'var(--instrument-tick-mark-secondary-color)'}>\n ${l.text}\n </text>\n </g>`\n );\n }\n\n return labels;\n }\n\n private watchFace(): SVGTemplateResult {\n const strokeWidth = 1;\n const th = this.totalHeight;\n const topTicksY = -th / 2;\n\n return svg`\n ${this.renderClipPath()}\n ${this.renderClipPath(-40)}\n <g clip-path=\"url(#frameClipPath)\">\n ${rect('frame-track', {\n width: this.width,\n height: this.trackHeight,\n y:\n th / 2 - this.trackHeight - (this.bottomBar ? this.ticksHeight : 0),\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-secondary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-secondary-color)',\n borderRadius: 0,\n })}\n ${rect('frame-ticks', {\n width: this.width,\n height: this.ticksHeight,\n y: topTicksY,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-primary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-primary-color)',\n borderRadius: 0,\n })}\n ${\n this.bottomBar\n ? rect('frame-bottom-bar', {\n width: this.width,\n height: this.ticksHeight,\n y: th / 2 - this.ticksHeight,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-primary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-primary-color)',\n borderRadius: 0,\n })\n : nothing\n }\n </g>\n ${rect('frame-outline', {\n width: this.width,\n height: th,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'inside',\n fillColor: 'none',\n borderRadius: this.borderRadius,\n })}\n `;\n }\n\n // ---------------------------------------------------------------------------\n // ROT (Rate of Turn) — linear\n // ---------------------------------------------------------------------------\n\n private getRotTrackY(): number {\n const th = this.totalHeight;\n if (this.rotPosition === LinearRotPosition.scale) {\n return -th / 2 + this.ticksHeight / 2;\n }\n if (this.bottomBar) {\n return th / 2 - this.ticksHeight / 2;\n }\n return this.height / 2 - this.trackHeight / 2;\n }\n\n private getRotColors(): {\n dotColor: string;\n barBgColor: string;\n } {\n const isEnhanced = this.rotPriority === Priority.enhanced;\n\n if (this.rotPortStarboard) {\n // For bar type, derive direction from bar positions (visual direction);\n // for dots, use spinner RPM.\n const direction =\n this.rotType === RotType.bar\n ? this.rotEndX - this.rotStartX\n : this._rotationsPerMinute;\n\n if (direction > 0) {\n return {\n dotColor: 'var(--instrument-starboard-secondary-color)',\n barBgColor: 'var(--instrument-starboard-primary-color)',\n };\n }\n if (direction < 0) {\n return {\n dotColor: 'var(--instrument-port-secondary-color)',\n barBgColor: 'var(--instrument-port-primary-color)',\n };\n }\n }\n\n return {\n dotColor: isEnhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)',\n barBgColor: isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)',\n };\n }\n\n private renderRot(): SVGTemplateResult | typeof nothing {\n if (!this.rotType) return nothing;\n\n const trackY = this.getRotTrackY();\n const {dotColor, barBgColor} = this.getRotColors();\n const canAnimateDots = this.rotDotSpacing > 0;\n\n if (this.rotType === RotType.bar) {\n const span = Math.abs(this.rotEndX - this.rotStartX);\n\n if (span < ROT_ZERO_DEADBAND_PX) {\n return renderLinearRotZeroPill(barBgColor, this.rotStartX, trackY);\n }\n\n if (span < BAR_HALF_THICKNESS) {\n return nothing;\n }\n\n return svg`\n ${renderLinearRotBarStatic({\n startX: this.rotStartX,\n endX: this.rotEndX,\n barColor: barBgColor,\n trackY,\n maskId: 'rot-bar-mask-linear',\n })}\n ${\n canAnimateDots\n ? svg`<g clip-path=\"url(#rot-bar-mask-linear)\">\n <g id=\"rot-spinner\">\n ${renderLinearRotBarDots(dotColor, trackY, this.rotDotSpacing, this.width)}\n </g>\n </g>`\n : nothing\n }\n `;\n }\n\n const isEnhanced = this.rotPriority === Priority.enhanced;\n const neutralDotsColor = isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n let dotsColor = neutralDotsColor;\n if (this.rotPortStarboard) {\n if (this._rotationsPerMinute > 0) {\n dotsColor = 'var(--instrument-starboard-secondary-color)';\n } else if (this._rotationsPerMinute < 0) {\n dotsColor = 'var(--instrument-port-secondary-color)';\n }\n }\n return canAnimateDots\n ? svg`\n <g id=\"rot-spinner\">\n ${renderLinearRotDots(dotsColor, trackY, this.rotDotSpacing, this.width)}\n </g>\n `\n : nothing;\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n const el = this.rotType\n ? this.renderRoot.querySelector('#rot-spinner')\n : null;\n\n if (!el) {\n this._rotController = disposeRotController(this, this._rotController);\n return;\n }\n\n const cyclePx = 360 * (this.rotDotSpacing / LINEAR_DOT_ANGLE_SPACING);\n\n if (!this._rotController || this._rotController.el !== el) {\n this._rotController = disposeRotController(this, this._rotController);\n this._rotController = new RateOfTurnController(\n this,\n el,\n this._rotationsPerMinute,\n cyclePx\n );\n } else {\n this._rotController.cyclePx = cyclePx;\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._rotController = disposeRotController(this, this._rotController);\n }\n\n override render() {\n const width = (this.width / 2 + this.padding) * 2;\n const th = this.totalHeight;\n const viewBox = `-${width / 2} -${th / 2} ${width} ${th}`;\n const scale = this.clientWidth / width;\n\n const contentOffsetY = this.bottomBar ? -this.ticksHeight / 2 : 0;\n\n return html`\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=${viewBox}\n style=\"--scale: ${scale}\"\n >\n ${this.watchFace()} ${this.renderLabelMask()}\n\n <g transform=\"translate(0, ${contentOffsetY})\">\n <g clip-path=\"url(#frameClipPath)\">\n ${this.tickmarks.map(\n (t) => svg`\n <g transform=\"translate(${-this.rotation * this.tickmarkSpacing}, 0)\">\n ${tickmark(t.angle, t.type, TickmarkStyle.regular)}\n </g>\n `\n )}\n </g>\n\n <g mask=\"url(#labelMask)\">${this.renderLabels(scale)}</g>\n </g>\n\n ${this.FOVIndicator}\n\n <g clip-path=\"url(#frameClipPath)\">${this.renderRot()}</g>\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-watch-flat': ObcWatchFlat;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch-flat.js","sources":["../../../src/navigation-instruments/watch-flat/watch-flat.ts"],"sourcesContent":["import {\n LitElement,\n PropertyValues,\n SVGTemplateResult,\n html,\n nothing,\n svg,\n unsafeCSS,\n} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './watch-flat.css?inline';\nimport {Tickmark, TickmarkStyle, tickmark} from './tickmark-flat.js';\nimport {rect} from '../../svghelpers/rectangular.js';\nimport {Label} from '../compass-flat/compass-flat.js';\nimport {customElement} from '../../decorator.js';\nimport {Priority} from '../types.js';\nimport {\n RotType,\n LinearRotPosition,\n renderLinearRotDots,\n renderLinearRotBarStatic,\n renderLinearRotBarDots,\n LINEAR_DOT_ANGLE_SPACING,\n renderLinearRotZeroPill,\n BAR_HALF_THICKNESS,\n ROT_ZERO_DEADBAND_PX,\n} from '../rate-of-turn/rot-renderer.js';\nimport {\n RateOfTurnController,\n disposeRotController,\n} from '../rate-of-turn/rate-of-turn.controller.js';\n\nexport {RotType, LinearRotPosition};\n\n@customElement('obc-watch-flat')\nexport class ObcWatchFlat extends LitElement {\n @property({type: Number}) width = 352;\n @property({type: Number}) height = 72;\n @property({type: Number}) padding = 0;\n @property({type: Number}) rotation = 0;\n @property({type: Number}) tickmarkSpacing = 0;\n @property({type: Number}) angleSetpoint: number | undefined;\n @property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];\n @property({type: Array, attribute: false}) labels: Label[] = [];\n @property({type: Array, attribute: false}) FOVIndicator: SVGTemplateResult[] =\n [];\n @property({type: Number}) trackHeight = (2 / 3) * this.height;\n @property({type: Number}) ticksHeight = this.height - this.trackHeight;\n @property({type: Number}) borderRadius = 8;\n @property({type: Boolean}) bottomBar = false;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: LinearRotPosition =\n LinearRotPosition.track;\n /** Bar start position in SVG user-space x-coordinates (center-origin). Computed by the parent instrument. */\n @property({type: Number}) rotStartX: number = 0;\n /** Bar end position in SVG user-space x-coordinates (center-origin). Computed by the parent instrument. */\n @property({type: Number}) rotEndX: number = 0;\n /**\n * Pixel spacing between adjacent dots in the linear ROT strip.\n * Must be > 0 to enable animation; the default `0` intentionally disables\n * the spinning dots so the parent instrument must supply a meaningful value\n * derived from the current scale (e.g. `LINEAR_DOT_ANGLE_SPACING * translationScale`).\n */\n @property({type: Number}) rotDotSpacing: number = 0;\n @property({type: String}) rotPriority: Priority = Priority.regular;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_PX;\n\n @property({type: Number})\n set rotationsPerMinute(value: number) {\n this._rotationsPerMinute = value;\n if (this._rotController) {\n this._rotController.rotationsPerMinute = value;\n }\n }\n get rotationsPerMinute() {\n return this._rotationsPerMinute;\n }\n\n private _rotationsPerMinute = 0;\n private _rotController?: RateOfTurnController;\n\n private get totalHeight(): number {\n return this.bottomBar ? this.height + this.ticksHeight : this.height;\n }\n\n private renderClipPath(offsetY: number = 0): SVGTemplateResult {\n return svg`\n <clipPath id=\"frameClipPath${offsetY === 0 ? '' : 'Tickmarks'}\">\n <rect x=\"${-this.width / 2}\" y=\"${-this.totalHeight / 2 + offsetY}\" \n width=\"${this.width}\" height=\"${this.totalHeight}\" \n rx=\"${this.borderRadius}\" />\n </clipPath>\n `;\n }\n\n private renderLabelMask(): SVGTemplateResult {\n return svg`\n <mask id=\"labelMask\">\n <rect x=\"${-this.width / 2}\" y=\"${-70}\" \n width=\"${this.width}\" height=\"${32}\"\n />\n <linearGradient id=\"fadeGradient\" gradientUnits=\"userSpaceOnUse\"\n x1=\"${-this.width / 2}\" y1=\"0\" x2=\"${this.width / 2}\" y2=\"0\">\n <stop offset=\"0%\" style=\"stop-color:black; stop-opacity:1;\" />\n <stop offset=\"10%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"50%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"90%\" style=\"stop-color:white; stop-opacity:1;\" />\n <stop offset=\"100%\" style=\"stop-color:black; stop-opacity:1;\" />\n </linearGradient>\n <rect x=\"${-this.width / 2}\" y=\"${-70}\" \n width=\"${this.width}\" height=\"${32}\"\n fill=\"url(#fadeGradient)\" />\n </mask>\n `;\n }\n\n private renderLabels(scale: number): SVGTemplateResult[] {\n const labels: SVGTemplateResult[] = [];\n\n for (const l of this.labels) {\n labels.push(\n svg`<g transform=\"translate(${-this.rotation * this.tickmarkSpacing}, ${-6 / scale})\">\n <text x=${l.x} y=${l.y} class=\"label\" fill=${'var(--instrument-tick-mark-secondary-color)'}>\n ${l.text}\n </text>\n </g>`\n );\n }\n\n return labels;\n }\n\n private watchFace(): SVGTemplateResult {\n const strokeWidth = 1;\n const th = this.totalHeight;\n const topTicksY = -th / 2;\n\n return svg`\n ${this.renderClipPath()}\n ${this.renderClipPath(-40)}\n <g clip-path=\"url(#frameClipPath)\">\n ${rect('frame-track', {\n width: this.width,\n height: this.trackHeight,\n y:\n th / 2 - this.trackHeight - (this.bottomBar ? this.ticksHeight : 0),\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-secondary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-secondary-color)',\n borderRadius: 0,\n })}\n ${rect('frame-ticks', {\n width: this.width,\n height: this.ticksHeight,\n y: topTicksY,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-primary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-primary-color)',\n borderRadius: 0,\n })}\n ${\n this.bottomBar\n ? rect('frame-bottom-bar', {\n width: this.width,\n height: this.ticksHeight,\n y: th / 2 - this.ticksHeight,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-primary-color)',\n strokePosition: 'inside',\n fillColor: 'var(--instrument-frame-primary-color)',\n borderRadius: 0,\n })\n : nothing\n }\n </g>\n ${rect('frame-outline', {\n width: this.width,\n height: th,\n strokeWidth: strokeWidth,\n strokeColor: 'var(--instrument-frame-tertiary-color)',\n strokePosition: 'inside',\n fillColor: 'none',\n borderRadius: this.borderRadius,\n })}\n `;\n }\n\n // ---------------------------------------------------------------------------\n // ROT (Rate of Turn) — linear\n // ---------------------------------------------------------------------------\n\n private getRotTrackY(): number {\n const th = this.totalHeight;\n if (this.rotPosition === LinearRotPosition.scale) {\n return -th / 2 + this.ticksHeight / 2;\n }\n if (this.bottomBar) {\n return th / 2 - this.ticksHeight / 2;\n }\n return this.height / 2 - this.trackHeight / 2;\n }\n\n private getRotColors(): {\n dotColor: string;\n barBgColor: string;\n } {\n const isEnhanced = this.rotPriority === Priority.enhanced;\n\n if (this.rotPortStarboard) {\n // For bar type, derive direction from bar positions (visual direction);\n // for dots, use spinner RPM.\n const direction =\n this.rotType === RotType.bar\n ? this.rotEndX - this.rotStartX\n : this._rotationsPerMinute;\n\n if (direction > 0) {\n return {\n dotColor: 'var(--instrument-starboard-secondary-color)',\n barBgColor: 'var(--instrument-starboard-primary-color)',\n };\n }\n if (direction < 0) {\n return {\n dotColor: 'var(--instrument-port-secondary-color)',\n barBgColor: 'var(--instrument-port-primary-color)',\n };\n }\n }\n\n return {\n dotColor: isEnhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)',\n barBgColor: isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)',\n };\n }\n\n private renderRot(): SVGTemplateResult | typeof nothing {\n if (!this.rotType) return nothing;\n\n const trackY = this.getRotTrackY();\n const {dotColor, barBgColor} = this.getRotColors();\n const canAnimateDots = this.rotDotSpacing > 0;\n\n if (this.rotType === RotType.bar) {\n const span = Math.abs(this.rotEndX - this.rotStartX);\n const zeroDb = Number.isFinite(this.rotAtZeroDeadband)\n ? this.rotAtZeroDeadband\n : ROT_ZERO_DEADBAND_PX;\n\n if (span < Math.max(zeroDb, BAR_HALF_THICKNESS)) {\n return renderLinearRotZeroPill(barBgColor, this.rotStartX, trackY);\n }\n\n return svg`\n ${renderLinearRotBarStatic({\n startX: this.rotStartX,\n endX: this.rotEndX,\n barColor: barBgColor,\n trackY,\n maskId: 'rot-bar-mask-linear',\n })}\n ${\n canAnimateDots\n ? svg`<g clip-path=\"url(#rot-bar-mask-linear)\">\n <g id=\"rot-spinner\">\n ${renderLinearRotBarDots(dotColor, trackY, this.rotDotSpacing, this.width)}\n </g>\n </g>`\n : nothing\n }\n `;\n }\n\n const isEnhanced = this.rotPriority === Priority.enhanced;\n const neutralDotsColor = isEnhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n let dotsColor = neutralDotsColor;\n if (this.rotPortStarboard) {\n if (this._rotationsPerMinute > 0) {\n dotsColor = 'var(--instrument-starboard-secondary-color)';\n } else if (this._rotationsPerMinute < 0) {\n dotsColor = 'var(--instrument-port-secondary-color)';\n }\n }\n return canAnimateDots\n ? svg`\n <g id=\"rot-spinner\">\n ${renderLinearRotDots(dotsColor, trackY, this.rotDotSpacing, this.width)}\n </g>\n `\n : nothing;\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n const el = this.rotType\n ? this.renderRoot.querySelector('#rot-spinner')\n : null;\n\n if (!el) {\n this._rotController = disposeRotController(this, this._rotController);\n return;\n }\n\n const cyclePx = 360 * (this.rotDotSpacing / LINEAR_DOT_ANGLE_SPACING);\n\n if (!this._rotController || this._rotController.el !== el) {\n this._rotController = disposeRotController(this, this._rotController);\n this._rotController = new RateOfTurnController(\n this,\n el,\n this._rotationsPerMinute,\n cyclePx\n );\n } else {\n this._rotController.cyclePx = cyclePx;\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._rotController = disposeRotController(this, this._rotController);\n }\n\n override render() {\n const width = (this.width / 2 + this.padding) * 2;\n const th = this.totalHeight;\n const viewBox = `-${width / 2} -${th / 2} ${width} ${th}`;\n const scale = this.clientWidth / width;\n\n const contentOffsetY = this.bottomBar ? -this.ticksHeight / 2 : 0;\n\n return html`\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=${viewBox}\n style=\"--scale: ${scale}\"\n >\n ${this.watchFace()} ${this.renderLabelMask()}\n\n <g transform=\"translate(0, ${contentOffsetY})\">\n <g clip-path=\"url(#frameClipPath)\">\n ${this.tickmarks.map(\n (t) => svg`\n <g transform=\"translate(${-this.rotation * this.tickmarkSpacing}, 0)\">\n ${tickmark(t.angle, t.type, TickmarkStyle.regular)}\n </g>\n `\n )}\n </g>\n\n <g mask=\"url(#labelMask)\">${this.renderLabels(scale)}</g>\n </g>\n\n ${this.FOVIndicator}\n\n <g clip-path=\"url(#frameClipPath)\">${this.renderRot()}</g>\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-watch-flat': ObcWatchFlat;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAmCO,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,QAAQ;AACR,SAAA,SAAS;AACT,SAAA,UAAU;AACV,SAAA,WAAW;AACX,SAAA,kBAAkB;AAED,SAAA,YAAwB,CAAA;AACxB,SAAA,SAAkB,CAAA;AAClB,SAAA,eACzC,CAAA;AACwB,SAAA,cAAe,IAAI,IAAK,KAAK;AAC7B,SAAA,cAAc,KAAK,SAAS,KAAK;AACjC,SAAA,eAAe;AACd,SAAA,YAAY;AAGb,SAAA,cACxB,kBAAkB;AAEM,SAAA,YAAoB;AAEpB,SAAA,UAAkB;AAOlB,SAAA,gBAAwB;AACxB,SAAA,cAAwB,SAAS;AAChC,SAAA,mBAA4B;AAC7B,SAAA,oBAA4B;AAatD,SAAQ,sBAAsB;AAAA,EAAA;AAAA,EAV9B,IAAI,mBAAmB,OAAe;AACpC,SAAK,sBAAsB;AAC3B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,qBAAqB;AAAA,IAC3C;AAAA,EACF;AAAA,EACA,IAAI,qBAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAKA,IAAY,cAAsB;AAChC,WAAO,KAAK,YAAY,KAAK,SAAS,KAAK,cAAc,KAAK;AAAA,EAChE;AAAA,EAEQ,eAAe,UAAkB,GAAsB;AAC7D,WAAO;AAAA,mCACwB,YAAY,IAAI,KAAK,WAAW;AAAA,mBAChD,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,KAAK,cAAc,IAAI,OAAO;AAAA,uBAClD,KAAK,KAAK,aAAa,KAAK,WAAW;AAAA,oBAC1C,KAAK,YAAY;AAAA;AAAA;AAAA,EAGnC;AAAA,EAEQ,kBAAqC;AAC3C,WAAO;AAAA;AAAA,mBAEQ,CAAC,KAAK,QAAQ,CAAC,QAAQ,GAAG;AAAA,uBACtB,KAAK,KAAK,aAAa,EAAE;AAAA;AAAA;AAAA,8BAGlB,CAAC,KAAK,QAAQ,CAAC,gBAAgB,KAAK,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAOxD,CAAC,KAAK,QAAQ,CAAC,QAAQ,GAAG;AAAA,uBACtB,KAAK,KAAK,aAAa,EAAE;AAAA;AAAA;AAAA;AAAA,EAI9C;AAAA,EAEQ,aAAa,OAAoC;AACvD,UAAM,SAA8B,CAAA;AAEpC,eAAW,KAAK,KAAK,QAAQ;AAC3B,aAAO;AAAA,QACL,8BAA8B,CAAC,KAAK,WAAW,KAAK,eAAe,KAAK,KAAK,KAAK;AAAA,oBACtE,EAAE,CAAC,MAAM,EAAE,CAAC,uBAAuB,6CAA6C;AAAA,cACtF,EAAE,IAAI;AAAA;AAAA;AAAA,MAAA;AAAA,IAIhB;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,YAA+B;AACrC,UAAM,cAAc;AACpB,UAAM,KAAK,KAAK;AAChB,UAAM,YAAY,CAAC,KAAK;AAExB,WAAO;AAAA,QACH,KAAK,gBAAgB;AAAA,QACrB,KAAK,eAAe,GAAG,CAAC;AAAA;AAAA,UAEtB,KAAK,eAAe;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,GACE,KAAK,IAAI,KAAK,eAAe,KAAK,YAAY,KAAK,cAAc;AAAA,MACnE;AAAA,MACA,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,cAAc;AAAA,IAAA,CACf,CAAC;AAAA,UACA,KAAK,eAAe;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,GAAG;AAAA,MACH;AAAA,MACA,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,cAAc;AAAA,IAAA,CACf,CAAC;AAAA,UAEA,KAAK,YACD,KAAK,oBAAoB;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,GAAG,KAAK,IAAI,KAAK;AAAA,MACjB;AAAA,MACA,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,cAAc;AAAA,IAAA,CACf,IACD,OACN;AAAA;AAAA,QAEA,KAAK,iBAAiB;AAAA,MACtB,OAAO,KAAK;AAAA,MACZ,QAAQ;AAAA,MACR;AAAA,MACA,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,cAAc,KAAK;AAAA,IAAA,CACpB,CAAC;AAAA;AAAA,EAEN;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAuB;AAC7B,UAAM,KAAK,KAAK;AAChB,QAAI,KAAK,gBAAgB,kBAAkB,OAAO;AAChD,aAAO,CAAC,KAAK,IAAI,KAAK,cAAc;AAAA,IACtC;AACA,QAAI,KAAK,WAAW;AAClB,aAAO,KAAK,IAAI,KAAK,cAAc;AAAA,IACrC;AACA,WAAO,KAAK,SAAS,IAAI,KAAK,cAAc;AAAA,EAC9C;AAAA,EAEQ,eAGN;AACA,UAAM,aAAa,KAAK,gBAAgB,SAAS;AAEjD,QAAI,KAAK,kBAAkB;AAGzB,YAAM,YACJ,KAAK,YAAY,QAAQ,MACrB,KAAK,UAAU,KAAK,YACpB,KAAK;AAEX,UAAI,YAAY,GAAG;AACjB,eAAO;AAAA,UACL,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,MAEhB;AACA,UAAI,YAAY,GAAG;AACjB,eAAO;AAAA,UACL,UAAU;AAAA,UACV,YAAY;AAAA,QAAA;AAAA,MAEhB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,UAAU,aACN,8CACA;AAAA,MACJ,YAAY,aACR,+CACA;AAAA,IAAA;AAAA,EAER;AAAA,EAEQ,YAAgD;AACtD,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,UAAM,SAAS,KAAK,aAAA;AACpB,UAAM,EAAC,UAAU,eAAc,KAAK,aAAA;AACpC,UAAM,iBAAiB,KAAK,gBAAgB;AAE5C,QAAI,KAAK,YAAY,QAAQ,KAAK;AAChC,YAAM,OAAO,KAAK,IAAI,KAAK,UAAU,KAAK,SAAS;AACnD,YAAM,SAAS,OAAO,SAAS,KAAK,iBAAiB,IACjD,KAAK,oBACL;AAEJ,UAAI,OAAO,KAAK,IAAI,QAAQ,kBAAkB,GAAG;AAC/C,eAAO,wBAAwB,YAAY,KAAK,WAAW,MAAM;AAAA,MACnE;AAEA,aAAO;AAAA,UACH,yBAAyB;AAAA,QACzB,QAAQ,KAAK;AAAA,QACb,MAAM,KAAK;AAAA,QACX,UAAU;AAAA,QACV;AAAA,QACA,QAAQ;AAAA,MAAA,CACT,CAAC;AAAA,UAEA,iBACI;AAAA;AAAA,kBAEI,uBAAuB,UAAU,QAAQ,KAAK,eAAe,KAAK,KAAK,CAAC;AAAA;AAAA,oBAG5E,OACN;AAAA;AAAA,IAEJ;AAEA,UAAM,aAAa,KAAK,gBAAgB,SAAS;AACjD,UAAM,mBAAmB,aACrB,+CACA;AACJ,QAAI,YAAY;AAChB,QAAI,KAAK,kBAAkB;AACzB,UAAI,KAAK,sBAAsB,GAAG;AAChC,oBAAY;AAAA,MACd,WAAW,KAAK,sBAAsB,GAAG;AACvC,oBAAY;AAAA,MACd;AAAA,IACF;AACA,WAAO,iBACH;AAAA;AAAA,cAEM,oBAAoB,WAAW,QAAQ,KAAK,eAAe,KAAK,KAAK,CAAC;AAAA;AAAA,YAG5E;AAAA,EACN;AAAA,EAES,QAAQ,SAA+B;AAC9C,UAAM,QAAQ,OAAO;AACrB,UAAM,KAAK,KAAK,UACZ,KAAK,WAAW,cAAc,cAAc,IAC5C;AAEJ,QAAI,CAAC,IAAI;AACP,WAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AACpE;AAAA,IACF;AAEA,UAAM,UAAU,OAAO,KAAK,gBAAgB;AAE5C,QAAI,CAAC,KAAK,kBAAkB,KAAK,eAAe,OAAO,IAAI;AACzD,WAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AACpE,WAAK,iBAAiB,IAAI;AAAA,QACxB;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,MAAA;AAAA,IAEJ,OAAO;AACL,WAAK,eAAe,UAAU;AAAA,IAChC;AAAA,EACF;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA;AACN,SAAK,iBAAiB,qBAAqB,MAAM,KAAK,cAAc;AAAA,EACtE;AAAA,EAES,SAAS;AAChB,UAAM,SAAS,KAAK,QAAQ,IAAI,KAAK,WAAW;AAChD,UAAM,KAAK,KAAK;AAChB,UAAM,UAAU,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE;AACvD,UAAM,QAAQ,KAAK,cAAc;AAEjC,UAAM,iBAAiB,KAAK,YAAY,CAAC,KAAK,cAAc,IAAI;AAEhE,WAAO;AAAA;AAAA;AAAA;AAAA,kBAIO,OAAO;AAAA,0BACC,KAAK;AAAA;AAAA,UAErB,KAAK,UAAA,CAAW,IAAI,KAAK,iBAAiB;AAAA;AAAA,qCAEf,cAAc;AAAA;AAAA,cAErC,KAAK,UAAU;AAAA,MACf,CAAC,MAAM;AAAA,wCACmB,CAAC,KAAK,WAAW,KAAK,eAAe;AAAA,kBAC3D,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,OAAO,CAAC;AAAA;AAAA;AAAA,IAAA,CAGrD;AAAA;AAAA;AAAA,sCAGyB,KAAK,aAAa,KAAK,CAAC;AAAA;AAAA;AAAA,UAGpD,KAAK,YAAY;AAAA;AAAA,6CAEkB,KAAK,WAAW;AAAA;AAAA;AAAA,EAG3D;AAGF;AAjVa,aAgVK,SAAS,UAAU,YAAY;AA/UrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,aACe,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,aAEe,WAAA,UAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,aAGe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,aAIe,WAAA,YAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,aAKe,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,aAMe,WAAA,iBAAA,CAAA;AACiB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAP9B,aAOgC,WAAA,aAAA,CAAA;AACA,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAR9B,aAQgC,WAAA,UAAA,CAAA;AACA,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAT9B,aASgC,WAAA,gBAAA,CAAA;AAEjB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAXb,aAWe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAZb,aAYe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAbb,aAae,WAAA,gBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAdd,aAcgB,WAAA,aAAA,CAAA;AAED,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhBb,aAgBe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjBb,aAiBe,WAAA,eAAA,CAAA;AAGA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApBb,aAoBe,WAAA,aAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtBb,aAsBe,WAAA,WAAA,CAAA;AAOA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Bb,aA6Be,WAAA,iBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Bb,aA8Be,WAAA,eAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA/Bd,aA+BgB,WAAA,oBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhCb,aAgCe,WAAA,qBAAA,CAAA;AAGtB,gBAAA;AAAA,EADH,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlCb,aAmCP,WAAA,sBAAA,CAAA;AAnCO,eAAN,gBAAA;AAAA,EADN,cAAc,gBAAgB;AAAA,GAClB,YAAA;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oicl/openbridge-webcomponents",
3
- "version": "0.0.20260409094807",
3
+ "version": "0.0.20260410061657",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",