@oicl/openbridge-webcomponents 2.0.0-next.111 → 2.0.0-next.113

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 (60) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +185 -29
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +180 -21
  4. package/dist/building-blocks/readout-block/readout-block.d.ts +29 -5
  5. package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -1
  6. package/dist/building-blocks/readout-block/readout-block.js +21 -7
  7. package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
  8. package/dist/navigation-instruments/compass/compass.d.ts +1 -1
  9. package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
  10. package/dist/navigation-instruments/compass/compass.js +1 -1
  11. package/dist/navigation-instruments/compass/compass.js.map +1 -1
  12. package/dist/navigation-instruments/current/current.d.ts +25 -0
  13. package/dist/navigation-instruments/current/current.d.ts.map +1 -1
  14. package/dist/navigation-instruments/current/current.js +25 -4
  15. package/dist/navigation-instruments/current/current.js.map +1 -1
  16. package/dist/navigation-instruments/heading/heading.js +1 -1
  17. package/dist/navigation-instruments/heading/heading.js.map +1 -1
  18. package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.d.ts +6 -0
  19. package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.d.ts.map +1 -1
  20. package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.js +8 -1
  21. package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.js.map +1 -1
  22. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts +5 -2
  23. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts.map +1 -1
  24. package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js.map +1 -1
  25. package/dist/navigation-instruments/readout/readout-formatters.d.ts +31 -0
  26. package/dist/navigation-instruments/readout/readout-formatters.d.ts.map +1 -1
  27. package/dist/navigation-instruments/readout/readout-formatters.js +55 -1
  28. package/dist/navigation-instruments/readout/readout-formatters.js.map +1 -1
  29. package/dist/navigation-instruments/readout/readout.d.ts +26 -1
  30. package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
  31. package/dist/navigation-instruments/readout/readout.js +16 -3
  32. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  33. package/dist/navigation-instruments/readout-list/readout-list.d.ts +6 -1
  34. package/dist/navigation-instruments/readout-list/readout-list.d.ts.map +1 -1
  35. package/dist/navigation-instruments/readout-list/readout-list.js +21 -4
  36. package/dist/navigation-instruments/readout-list/readout-list.js.map +1 -1
  37. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +26 -1
  38. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  39. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +15 -3
  40. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  41. package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.d.ts +6 -0
  42. package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.d.ts.map +1 -1
  43. package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.js +19 -4
  44. package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.js.map +1 -1
  45. package/dist/navigation-instruments/watch/environment.d.ts +8 -0
  46. package/dist/navigation-instruments/watch/environment.d.ts.map +1 -1
  47. package/dist/navigation-instruments/watch/environment.js +3 -0
  48. package/dist/navigation-instruments/watch/environment.js.map +1 -1
  49. package/dist/navigation-instruments/watch/force-pattern.d.ts +20 -2
  50. package/dist/navigation-instruments/watch/force-pattern.d.ts.map +1 -1
  51. package/dist/navigation-instruments/watch/force-pattern.js +12 -5
  52. package/dist/navigation-instruments/watch/force-pattern.js.map +1 -1
  53. package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
  54. package/dist/navigation-instruments/watch/watch.js +6 -4
  55. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  56. package/dist/navigation-instruments/wind/wind.d.ts +5 -2
  57. package/dist/navigation-instruments/wind/wind.d.ts.map +1 -1
  58. package/dist/navigation-instruments/wind/wind.js +5 -1
  59. package/dist/navigation-instruments/wind/wind.js.map +1 -1
  60. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"readout-block.js","sources":["../../../src/building-blocks/readout-block/readout-block.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS, type TemplateResult} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './readout-block.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../components/textbox/textbox.js';\nimport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nimport '../../icons/icon-input-right.js';\nimport '../../icons/icon-notification-advice.js';\nimport {\n formatNumericValue,\n readoutFormattedInteger,\n type ReadoutNumericFormatOptions,\n} from '../../navigation-instruments/readout/readout-formatters.js';\nimport {\n type AlertFrameConfig,\n wrapWithAlertFrame,\n} from '../../components/alert-frame/alert-frame.js';\n\n// Re-exported so consumers can configure typography without a second import path.\nexport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\n\n/**\n * Semantic variant of the block. Drives the default marker icon and the\n * colour token; the layout is identical across variants.\n * - `value`: the primary reading (no default marker icon).\n * - `setpoint`: a setpoint reference (default `input-right` marker).\n * - `advice`: an advisory reference (default `notification-advice` marker).\n */\nexport enum ReadoutBlockVariant {\n value = 'value',\n setpoint = 'setpoint',\n advice = 'advice',\n}\n\n/**\n * Density tier of the block — drives icon size, the icon↔number gap, and the\n * degree-column width tier. The number typography size is controlled\n * independently via {@link ObcReadoutBlock.valueSize} so a parent can de-emphasise\n * one block relative to another within the same tier.\n */\nexport enum ReadoutBlockSize {\n small = 'small',\n medium = 'medium',\n large = 'large',\n}\n\n/**\n * Per-block measurement quality, rendered as a non-shifting outline chip.\n * - `low-integrity`: the value is suspect.\n * - `invalid`: the value is invalid.\n */\nexport enum ReadoutBlockDataQuality {\n lowIntegrity = 'low-integrity',\n invalid = 'invalid',\n}\n\n/**\n * Pop-up fade phase for a setpoint block. Driven by the parent's setpoint\n * interaction state machine; only meaningful for `role=\"setpoint\"`.\n */\nexport enum ReadoutBlockHidePhase {\n none = 'none',\n hiding = 'hiding',\n hidden = 'hidden',\n}\n\n/**\n * `<obc-readout-block>` – the most atomic readout primitive: a single\n * cap-height-aligned, width-reservable numeric segment (value / setpoint /\n * advice).\n *\n * It renders one `obc-textbox` number with optional hinted leading zeros, a\n * reservable width, an optional leading marker icon (via the `icon` slot or the\n * role default), an optional trailing degree glyph, an `off`/unavailable text\n * state, per-block data-quality and an optional per-block alert frame.\n *\n * This is a building block used inside `obc-readout-list-item` (and, in a future\n * refactor, inside `obc-readout`); it is not normally used on its own. Colour is\n * inherited from the host context (the parent sets the role colour), so the\n * block stays neutral until placed.\n *\n * @experimental Pilot for the new primitives + per-block options Readout API; the\n * API may change in a future release.\n *\n * @slot icon - Replaces the role's default marker icon.\n *\n * @csspart block - The block container (carries role / tone / data-quality).\n * @csspart block-content - The number + degree group.\n * @csspart block-text - The `obc-textbox` rendering the number.\n * @csspart block-icon - The leading marker-icon container.\n * @csspart degree - The trailing degree-glyph column.\n */\n@customElement('obc-readout-block')\nexport class ObcReadoutBlock extends LitElement {\n /** Semantic variant (value / setpoint / advice). */\n @property({type: String}) variant: ReadoutBlockVariant =\n ReadoutBlockVariant.value;\n\n /** The numeric value; `null`/`undefined` renders a dash. */\n @property({type: Number}) value: number | null = null;\n\n /** Density tier — icon size, gap, degree tier. */\n @property({type: String}) size: ReadoutBlockSize = ReadoutBlockSize.small;\n\n /**\n * Resolved number-typography size. When unset it is derived from `size`\n * (small→s, medium→m, large→l), so a parent that de-emphasises a block (e.g.\n * a secondary setpoint) can pass a smaller size without changing the tier.\n */\n @property({type: String}) valueSize?: ObcTextboxSize;\n\n /** Accent (in-command) colour tone. */\n @property({type: Boolean}) enhanced = false;\n\n /** Number font weight (regular / semibold / bold); colour is independent. */\n @property({type: String}) weight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n\n /** Render the trailing cap-height degree glyph (`°`). */\n @property({type: Boolean}) hasDegree = false;\n\n /** Show the leading marker-icon container (always on for setpoint/advice). */\n @property({type: Boolean}) hasIcon = false;\n\n /** Number of fraction digits. */\n @property({type: Number}) fractionDigits = 0;\n\n /** Integer digits to reserve / hint (independent of `fractionDigits`). */\n @property({type: Number}) maxDigits = 0;\n\n /** Render muted leading zeros filling the integer part to `maxDigits`. */\n @property({type: Boolean}) hintedZeros = false;\n\n /** Explicit longest string to reserve width for (e.g. `\"0000.0\"`). */\n @property({type: String}) spaceReserver?: string;\n\n /** Render `offText` instead of a number (e.g. equipment powered down). */\n @property({type: Boolean}) off = false;\n\n /** Text shown when `off` is true. */\n @property({type: String}) offText = 'OFF';\n\n /** Text alignment of the number within its reserved width. */\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n\n /** Per-block measurement quality (outline chip). */\n @property({type: String}) dataQuality?: ReadoutBlockDataQuality;\n\n // `boolean | …` (not `false | …`): the generated Angular wrapper widens a\n // literal-`false` union to `boolean`. `wrapWithAlertFrame` treats any\n // non-object as \"no frame\", so accepting `boolean` is harmless.\n /** Per-block alert frame; nests inside any parent alert frame. */\n @property({type: Object}) alert: boolean | AlertFrameConfig = false;\n\n /** Setpoint focus (touch) state — only meaningful for `role=\"setpoint\"`. */\n @property({type: Boolean}) touching = false;\n\n /** Setpoint pop-up fade phase — only meaningful for `role=\"setpoint\"`. */\n @property({type: String}) hidePhase: ReadoutBlockHidePhase =\n ReadoutBlockHidePhase.none;\n\n @state() private hasAssignedIcon = false;\n\n private get resolvedValueSize(): ObcTextboxSize {\n if (this.valueSize) {\n return this.valueSize;\n }\n switch (this.size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n }\n\n private get numericFormatOptions(): ReadoutNumericFormatOptions {\n return {\n showZeroPadding: false,\n minValueLength: this.maxDigits,\n fractionDigits: this.fractionDigits,\n };\n }\n\n /** Widest possible value string for width reservation (e.g. `\"000.0\"`). */\n private get reserverText(): string {\n const maxDigits = this.maxDigits;\n if (maxDigits <= 0) {\n return '';\n }\n const integer = '0'.repeat(Math.max(maxDigits, 1));\n return this.fractionDigits > 0\n ? `${integer}.${'0'.repeat(this.fractionDigits)}`\n : integer;\n }\n\n /**\n * Effective width reserver: the wider of the explicit `spaceReserver` and the\n * `maxDigits`/`fractionDigits`-derived reserve, so an explicit reserver can\n * never reserve *less* than the formatted value needs. Under tabular-nums the\n * rendered width is proportional to character count, so \"wider\" compares length.\n */\n private widerReserver(explicit: string | undefined, derived: string): string {\n if (!explicit) {\n return derived;\n }\n if (!derived) {\n return explicit;\n }\n return explicit.length >= derived.length ? explicit : derived;\n }\n\n private dataQualityClasses(): Record<string, boolean> {\n return {\n 'data-low-integrity':\n this.dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': this.dataQuality === ReadoutBlockDataQuality.invalid,\n };\n }\n\n private onIconSlotChange = (event: Event): void => {\n // `slotchange` fires after the first render once content is (re)assigned,\n // so it covers the initial state without a firstUpdated re-render.\n this.hasAssignedIcon =\n (event.target as HTMLSlotElement).assignedElements({flatten: true})\n .length > 0;\n };\n\n private renderIcon(): TemplateResult | typeof nothing {\n // Value blocks only show an icon when asked; setpoint/advice always reserve\n // their marker. The role default is rendered as a direct child (so it sizes\n // via `.block-icon obi-*`) and hidden once an icon is assigned to the slot —\n // `{flatten: true}` sees through a forwarded-but-empty parent slot, so the\n // default still shows when the consumer overrides nothing.\n const showIcon = this.variant !== ReadoutBlockVariant.value || this.hasIcon;\n if (!showIcon) {\n return nothing;\n }\n let fallback: TemplateResult | typeof nothing = nothing;\n if (this.variant === ReadoutBlockVariant.setpoint) {\n fallback = html`<obi-input-right></obi-input-right>`;\n } else if (this.variant === ReadoutBlockVariant.advice) {\n fallback = html`<obi-notification-advice></obi-notification-advice>`;\n }\n return html`<span class=\"block-icon\" part=\"block-icon\" aria-hidden=\"true\">\n <slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot>\n ${this.hasAssignedIcon ? nothing : fallback}\n </span>`;\n }\n\n /**\n * A cap-height `°` column whose width scales with the number size. Inherits the\n * block's colour.\n */\n private renderDegreeGlyph(size: ObcTextboxSize): TemplateResult {\n return html`\n <span\n class=${classMap({\n 'degree-column': true,\n [`degree-${size}`]: true,\n 'degree-inherit': true,\n })}\n part=\"degree\"\n >\n <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\"\n >°</obc-textbox\n >\n </span>\n `;\n }\n\n override render() {\n const valueSize = this.resolvedValueSize;\n const formatOptions = this.numericFormatOptions;\n const valueForFormat = this.value ?? undefined;\n const text = this.off\n ? this.offText\n : formatNumericValue(valueForFormat, formatOptions);\n // Hinted zeros pad the INTEGER part up to `maxDigits`, independent of\n // `fractionDigits` (the decimal point and fraction digits never count toward\n // `maxDigits`). Negative / dashed values are not padded. Example: value 1.2,\n // maxDigits 3, fractionDigits 1 → \"001.2\".\n const hintCount =\n this.off ||\n !this.hintedZeros ||\n valueForFormat === undefined ||\n valueForFormat < 0\n ? 0\n : Math.max(this.maxDigits - readoutFormattedInteger(text), 0);\n const hinted = hintCount > 0 ? '0'.repeat(hintCount) : '';\n // Hinted zeros own the width — they already fill to `maxDigits` — so when\n // `hintedZeros` is enabled an explicit `spaceReserver` is ignored (it has\n // higher priority). Otherwise the wider of the explicit reserver and the\n // `maxDigits`-derived reserve wins.\n const reserver = this.hintedZeros\n ? this.reserverText\n : this.widerReserver(this.spaceReserver, this.reserverText);\n\n const block = html`\n <div\n class=${classMap({\n block: true,\n [`block-${this.variant}`]: true,\n [`size-${this.size}`]: true,\n 'tone-enhanced': this.enhanced,\n touching: this.touching,\n 'is-hiding': this.hidePhase === ReadoutBlockHidePhase.hiding,\n 'is-hidden': this.hidePhase === ReadoutBlockHidePhase.hidden,\n ...this.dataQualityClasses(),\n })}\n part=\"block block-${this.variant}\"\n >\n ${this.renderIcon()}\n <span class=\"block-content\" part=\"block-content\">\n <obc-textbox\n class=\"block-text\"\n part=\"block-text\"\n .size=${valueSize}\n .fontWeight=${this.weight}\n .alignment=${this.alignment}\n .tabularNums=${true}\n >\n ${hinted\n ? html`<span class=\"hinted-zero\" aria-hidden=\"true\"\n >${hinted}</span\n >`\n : nothing}${text}\n ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing}\n </obc-textbox>\n ${this.hasDegree ? this.renderDegreeGlyph(valueSize) : nothing}\n </span>\n </div>\n `;\n return wrapWithAlertFrame(this.alert ?? false, block);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-readout-block': ObcReadoutBlock;\n }\n}\n"],"names":["ReadoutBlockVariant","ReadoutBlockSize","ReadoutBlockDataQuality","ReadoutBlockHidePhase"],"mappings":"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"}
1
+ {"version":3,"file":"readout-block.js","sources":["../../../src/building-blocks/readout-block/readout-block.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS, type TemplateResult} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport componentStyle from './readout-block.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../components/textbox/textbox.js';\nimport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nimport '../../icons/icon-input-right.js';\nimport '../../icons/icon-notification-advice.js';\nimport {\n formatNumericValue,\n readoutFormattedInteger,\n assertReadoutValueType,\n resolveReadoutNumericValue,\n resolveReadoutTextValue,\n ReadoutValueType,\n type ReadoutNumericFormatOptions,\n} from '../../navigation-instruments/readout/readout-formatters.js';\nimport {\n type AlertFrameConfig,\n wrapWithAlertFrame,\n} from '../../components/alert-frame/alert-frame.js';\n\n// Re-exported so consumers can configure typography without a second import path.\nexport {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n ObcTextboxAlignment,\n} from '../../components/textbox/textbox.js';\nexport {ReadoutValueType} from '../../navigation-instruments/readout/readout-formatters.js';\n\n/**\n * Semantic variant of the block. Drives the default marker icon and the\n * colour token; the layout is identical across variants.\n * - `value`: the primary reading (no default marker icon).\n * - `setpoint`: a setpoint reference (default `input-right` marker).\n * - `advice`: an advisory reference (default `notification-advice` marker).\n */\nexport enum ReadoutBlockVariant {\n value = 'value',\n setpoint = 'setpoint',\n advice = 'advice',\n}\n\n/**\n * Density tier of the block — drives icon size, the icon↔number gap, and the\n * degree-column width tier. The number typography size is controlled\n * independently via {@link ObcReadoutBlock.valueSize} so a parent can de-emphasise\n * one block relative to another within the same tier.\n */\nexport enum ReadoutBlockSize {\n small = 'small',\n medium = 'medium',\n large = 'large',\n}\n\n/**\n * Per-block measurement quality, rendered as a non-shifting outline chip.\n * - `low-integrity`: the value is suspect.\n * - `invalid`: the value is invalid.\n */\nexport enum ReadoutBlockDataQuality {\n lowIntegrity = 'low-integrity',\n invalid = 'invalid',\n}\n\n/**\n * Pop-up fade phase for a setpoint block. Driven by the parent's setpoint\n * interaction state machine; only meaningful for `role=\"setpoint\"`.\n */\nexport enum ReadoutBlockHidePhase {\n none = 'none',\n hiding = 'hiding',\n hidden = 'hidden',\n}\n\n/**\n * `<obc-readout-block>` – the most atomic readout primitive: a single\n * cap-height-aligned, width-reservable numeric segment (value / setpoint /\n * advice).\n *\n * It renders one `obc-textbox` number with optional hinted leading zeros, a\n * reservable width, an optional leading marker icon (via the `icon` slot or the\n * role default), an optional trailing degree glyph, an `off`/unavailable text\n * state, per-block data-quality and an optional per-block alert frame.\n *\n * Setting `valueType` to `text` renders `value` verbatim (e.g.\n * `\"Auto\"`) instead of a formatted number.\n *\n * This is a building block used inside `obc-readout-list-item` (and, in a future\n * refactor, inside `obc-readout`); it is not normally used on its own. Colour is\n * inherited from the host context (the parent sets the role colour), so the\n * block stays neutral until placed.\n *\n * @experimental Pilot for the new primitives + per-block options Readout API; the\n * API may change in a future release.\n *\n * @slot icon - Replaces the role's default marker icon.\n *\n * @csspart block - The block container (carries role / tone / data-quality).\n * @csspart block-content - The number + degree group.\n * @csspart block-text - The `obc-textbox` rendering the number.\n * @csspart block-icon - The leading marker-icon container.\n * @csspart degree - The trailing degree-glyph column.\n */\n@customElement('obc-readout-block')\nexport class ObcReadoutBlock extends LitElement {\n /** Semantic variant (value / setpoint / advice). */\n @property({type: String}) variant: ReadoutBlockVariant =\n ReadoutBlockVariant.value;\n\n /**\n * The value; `null`/`undefined` renders a dash. A number by default, or text\n * when {@link valueType} is `text`.\n */\n @property({type: String}) value: number | string | null = null;\n\n /**\n * How {@link value} is interpreted. `number` (default) formats it via\n * `fractionDigits`; `text` renders it verbatim and ignores the numeric\n * format options. Passing text while this is `number` throws.\n */\n @property({type: String}) valueType: ReadoutValueType =\n ReadoutValueType.number;\n\n /** Density tier — icon size, gap, degree tier. */\n @property({type: String}) size: ReadoutBlockSize = ReadoutBlockSize.small;\n\n /**\n * Resolved number-typography size. When unset it is derived from `size`\n * (small→s, medium→m, large→l), so a parent that de-emphasises a block (e.g.\n * a secondary setpoint) can pass a smaller size without changing the tier.\n */\n @property({type: String}) valueSize?: ObcTextboxSize;\n\n /** Accent (in-command) colour tone. */\n @property({type: Boolean}) enhanced = false;\n\n /** Number font weight (regular / semibold / bold); colour is independent. */\n @property({type: String}) weight: ObcTextboxFontWeight =\n ObcTextboxFontWeight.regular;\n\n /** Render the trailing cap-height degree glyph (`°`). */\n @property({type: Boolean}) hasDegree = false;\n\n /** Show the leading marker-icon container (always on for setpoint/advice). */\n @property({type: Boolean}) hasIcon = false;\n\n /**\n * Number of fraction digits.\n * @availableWhen valueType==number\n */\n @property({type: Number}) fractionDigits = 0;\n\n /**\n * Integer digits to reserve / hint (independent of `fractionDigits`).\n * @availableWhen valueType==number\n */\n @property({type: Number}) maxDigits = 0;\n\n /**\n * Render muted leading zeros filling the integer part to `maxDigits`.\n * @availableWhen valueType==number\n */\n @property({type: Boolean}) hintedZeros = false;\n\n /** Explicit longest string to reserve width for (e.g. `\"0000.0\"`). */\n @property({type: String}) spaceReserver?: string;\n\n /** Render `offText` instead of a number (e.g. equipment powered down). */\n @property({type: Boolean}) off = false;\n\n /** Text shown when `off` is true. */\n @property({type: String}) offText = 'OFF';\n\n /** Text alignment of the number within its reserved width. */\n @property({type: String}) alignment: ObcTextboxAlignment =\n ObcTextboxAlignment.Right;\n\n /** Per-block measurement quality (outline chip). */\n @property({type: String}) dataQuality?: ReadoutBlockDataQuality;\n\n // `boolean | …` (not `false | …`): the generated Angular wrapper widens a\n // literal-`false` union to `boolean`. `wrapWithAlertFrame` treats any\n // non-object as \"no frame\", so accepting `boolean` is harmless.\n /** Per-block alert frame; nests inside any parent alert frame. */\n @property({type: Object}) alert: boolean | AlertFrameConfig = false;\n\n /** Setpoint focus (touch) state — only meaningful for `role=\"setpoint\"`. */\n @property({type: Boolean}) touching = false;\n\n /** Setpoint pop-up fade phase — only meaningful for `role=\"setpoint\"`. */\n @property({type: String}) hidePhase: ReadoutBlockHidePhase =\n ReadoutBlockHidePhase.none;\n\n @state() private hasAssignedIcon = false;\n\n private get resolvedValueSize(): ObcTextboxSize {\n if (this.valueSize) {\n return this.valueSize;\n }\n switch (this.size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n }\n\n private get numericFormatOptions(): ReadoutNumericFormatOptions {\n return {\n showZeroPadding: false,\n minValueLength: this.maxDigits,\n fractionDigits: this.fractionDigits,\n };\n }\n\n /** Widest possible value string for width reservation (e.g. `\"000.0\"`). */\n private get reserverText(): string {\n const maxDigits = this.maxDigits;\n if (maxDigits <= 0) {\n return '';\n }\n const integer = '0'.repeat(Math.max(maxDigits, 1));\n return this.fractionDigits > 0\n ? `${integer}.${'0'.repeat(this.fractionDigits)}`\n : integer;\n }\n\n /**\n * Effective width reserver: the wider of the explicit `spaceReserver` and the\n * `maxDigits`/`fractionDigits`-derived reserve, so an explicit reserver can\n * never reserve *less* than the formatted value needs. Under tabular-nums the\n * rendered width is proportional to character count, so \"wider\" compares length.\n */\n private widerReserver(explicit: string | undefined, derived: string): string {\n if (!explicit) {\n return derived;\n }\n if (!derived) {\n return explicit;\n }\n return explicit.length >= derived.length ? explicit : derived;\n }\n\n private dataQualityClasses(): Record<string, boolean> {\n return {\n 'data-low-integrity':\n this.dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': this.dataQuality === ReadoutBlockDataQuality.invalid,\n };\n }\n\n private onIconSlotChange = (event: Event): void => {\n // `slotchange` fires after the first render once content is (re)assigned,\n // so it covers the initial state without a firstUpdated re-render.\n this.hasAssignedIcon =\n (event.target as HTMLSlotElement).assignedElements({flatten: true})\n .length > 0;\n };\n\n private renderIcon(): TemplateResult | typeof nothing {\n // Value blocks only show an icon when asked; setpoint/advice always reserve\n // their marker. The role default is rendered as a direct child (so it sizes\n // via `.block-icon obi-*`) and hidden once an icon is assigned to the slot —\n // `{flatten: true}` sees through a forwarded-but-empty parent slot, so the\n // default still shows when the consumer overrides nothing.\n const showIcon = this.variant !== ReadoutBlockVariant.value || this.hasIcon;\n if (!showIcon) {\n return nothing;\n }\n let fallback: TemplateResult | typeof nothing = nothing;\n if (this.variant === ReadoutBlockVariant.setpoint) {\n fallback = html`<obi-input-right></obi-input-right>`;\n } else if (this.variant === ReadoutBlockVariant.advice) {\n fallback = html`<obi-notification-advice></obi-notification-advice>`;\n }\n return html`<span class=\"block-icon\" part=\"block-icon\" aria-hidden=\"true\">\n <slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot>\n ${this.hasAssignedIcon ? nothing : fallback}\n </span>`;\n }\n\n /**\n * A cap-height `°` column whose width scales with the number size. Inherits the\n * block's colour.\n */\n private renderDegreeGlyph(size: ObcTextboxSize): TemplateResult {\n return html`\n <span\n class=${classMap({\n 'degree-column': true,\n [`degree-${size}`]: true,\n 'degree-inherit': true,\n })}\n part=\"degree\"\n >\n <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\"\n >°</obc-textbox\n >\n </span>\n `;\n }\n\n protected override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n // Validated on EVERY update, deliberately NOT gated on `value`/`valueType`\n // appearing in `changed`. When this assertion throws, Lit's `performUpdate`\n // catch calls `__markUpdated()`, which clears the changed-properties map. A\n // later update driven by any OTHER property — inside `obc-readout-list`,\n // `align()` writing the shared reservers — would then see no `value` in\n // `changed`, skip the check, and render the invalid value as a plain dash:\n // exactly the silent failure this assertion exists to prevent.\n assertReadoutValueType('obc-readout-block', this.value, this.valueType);\n }\n\n override render() {\n const valueSize = this.resolvedValueSize;\n const formatOptions = this.numericFormatOptions;\n const isTextMode = this.valueType === ReadoutValueType.text;\n const valueForFormat = resolveReadoutNumericValue(\n this.value,\n this.valueType\n );\n const textValue = resolveReadoutTextValue(this.value, this.valueType);\n // Text mode renders verbatim and ignores the numeric format options; a\n // blank / missing text value still falls back to the unavailable dash.\n const text = this.off\n ? this.offText\n : isTextMode\n ? (textValue ?? '-')\n : formatNumericValue(valueForFormat, formatOptions);\n // Hinted zeros pad the INTEGER part up to `maxDigits`, independent of\n // `fractionDigits` (the decimal point and fraction digits never count toward\n // `maxDigits`). Negative / dashed values are not padded. Example: value 1.2,\n // maxDigits 3, fractionDigits 1 → \"001.2\".\n const hintCount =\n this.off ||\n isTextMode ||\n !this.hintedZeros ||\n valueForFormat === undefined ||\n valueForFormat < 0\n ? 0\n : Math.max(this.maxDigits - readoutFormattedInteger(text), 0);\n const hinted = hintCount > 0 ? '0'.repeat(hintCount) : '';\n // Hinted zeros own the width — they already fill to `maxDigits` — so when\n // `hintedZeros` is enabled an explicit `spaceReserver` is ignored (it has\n // higher priority). Otherwise the wider of the explicit reserver and the\n // `maxDigits`-derived reserve wins.\n // Text mode ignores the `maxDigits`-derived numeric reserve — only an\n // explicit `spaceReserver` still applies.\n const reserver = isTextMode\n ? (this.spaceReserver ?? '')\n : this.hintedZeros\n ? this.reserverText\n : this.widerReserver(this.spaceReserver, this.reserverText);\n\n const block = html`\n <div\n class=${classMap({\n block: true,\n [`block-${this.variant}`]: true,\n [`size-${this.size}`]: true,\n 'tone-enhanced': this.enhanced,\n touching: this.touching,\n 'is-hiding': this.hidePhase === ReadoutBlockHidePhase.hiding,\n 'is-hidden': this.hidePhase === ReadoutBlockHidePhase.hidden,\n ...this.dataQualityClasses(),\n })}\n part=\"block block-${this.variant}\"\n >\n ${this.renderIcon()}\n <span class=\"block-content\" part=\"block-content\">\n <obc-textbox\n class=\"block-text\"\n part=\"block-text\"\n .size=${valueSize}\n .fontWeight=${this.weight}\n .alignment=${this.alignment}\n .tabularNums=${true}\n >\n ${hinted\n ? html`<span class=\"hinted-zero\" aria-hidden=\"true\"\n >${hinted}</span\n >`\n : nothing}${text}\n ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing}\n </obc-textbox>\n ${this.hasDegree ? this.renderDegreeGlyph(valueSize) : nothing}\n </span>\n </div>\n `;\n return wrapWithAlertFrame(this.alert ?? false, block);\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-readout-block': ObcReadoutBlock;\n }\n}\n"],"names":["ReadoutBlockVariant","ReadoutBlockSize","ReadoutBlockDataQuality","ReadoutBlockHidePhase"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0CO,IAAK,wCAAAA,yBAAL;AACLA,uBAAA,OAAA,IAAQ;AACRA,uBAAA,UAAA,IAAW;AACXA,uBAAA,QAAA,IAAS;AAHC,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAYL,IAAK,qCAAAC,sBAAL;AACLA,oBAAA,OAAA,IAAQ;AACRA,oBAAA,QAAA,IAAS;AACTA,oBAAA,OAAA,IAAQ;AAHE,SAAAA;AAAA,GAAA,oBAAA,CAAA,CAAA;AAWL,IAAK,4CAAAC,6BAAL;AACLA,2BAAA,cAAA,IAAe;AACfA,2BAAA,SAAA,IAAU;AAFA,SAAAA;AAAA,GAAA,2BAAA,CAAA,CAAA;AASL,IAAK,0CAAAC,2BAAL;AACLA,yBAAA,MAAA,IAAO;AACPA,yBAAA,QAAA,IAAS;AACTA,yBAAA,QAAA,IAAS;AAHC,SAAAA;AAAA,GAAA,yBAAA,CAAA,CAAA;AAoCL,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAAzC,cAAA;AAAA,UAAA,GAAA,SAAA;AAEqB,SAAA,UACxB;AAMwB,SAAA,QAAgC;AAOhC,SAAA,YACxB,iBAAiB;AAGO,SAAA,OAAyB;AAUxB,SAAA,WAAW;AAGZ,SAAA,SACxB,qBAAqB;AAGI,SAAA,YAAY;AAGZ,SAAA,UAAU;AAMX,SAAA,iBAAiB;AAMjB,SAAA,YAAY;AAMX,SAAA,cAAc;AAMd,SAAA,MAAM;AAGP,SAAA,UAAU;AAGV,SAAA,YACxB,oBAAoB;AASI,SAAA,QAAoC;AAGnC,SAAA,WAAW;AAGZ,SAAA,YACxB;AAEO,SAAQ,kBAAkB;AA4DnC,SAAQ,mBAAmB,CAAC,UAAuB;AAGjD,WAAK,kBACF,MAAM,OAA2B,iBAAiB,EAAC,SAAS,KAAA,CAAK,EAC/D,SAAS;AAAA,IAChB;AAAA,EAAA;AAAA,EAhEA,IAAY,oBAAoC;AAC9C,QAAI,KAAK,WAAW;AAClB,aAAO,KAAK;AAAA,IACd;AACA,YAAQ,KAAK,MAAA;AAAA,MACX,KAAK;AACH,eAAO,eAAe;AAAA,MACxB,KAAK;AACH,eAAO,eAAe;AAAA,MACxB;AACE,eAAO,eAAe;AAAA,IAAA;AAAA,EAE5B;AAAA,EAEA,IAAY,uBAAoD;AAC9D,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,gBAAgB,KAAK;AAAA,MACrB,gBAAgB,KAAK;AAAA,IAAA;AAAA,EAEzB;AAAA;AAAA,EAGA,IAAY,eAAuB;AACjC,UAAM,YAAY,KAAK;AACvB,QAAI,aAAa,GAAG;AAClB,aAAO;AAAA,IACT;AACA,UAAM,UAAU,IAAI,OAAO,KAAK,IAAI,WAAW,CAAC,CAAC;AACjD,WAAO,KAAK,iBAAiB,IACzB,GAAG,OAAO,IAAI,IAAI,OAAO,KAAK,cAAc,CAAC,KAC7C;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,cAAc,UAA8B,SAAyB;AAC3E,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AACA,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,WAAO,SAAS,UAAU,QAAQ,SAAS,WAAW;AAAA,EACxD;AAAA,EAEQ,qBAA8C;AACpD,WAAO;AAAA,MACL,sBACE,KAAK,gBAAgB;AAAA,MACvB,gBAAgB,KAAK,gBAAgB;AAAA;AAAA,IAAA;AAAA,EAEzC;AAAA,EAUQ,aAA8C;AAMpD,UAAM,WAAW,KAAK,YAAY,WAA6B,KAAK;AACpE,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AACA,QAAI,WAA4C;AAChD,QAAI,KAAK,YAAY,YAA8B;AACjD,iBAAW;AAAA,IACb,WAAW,KAAK,YAAY,UAA4B;AACtD,iBAAW;AAAA,IACb;AACA,WAAO;AAAA,sCAC2B,KAAK,gBAAgB;AAAA,QACnD,KAAK,kBAAkB,UAAU,QAAQ;AAAA;AAAA,EAE/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,MAAsC;AAC9D,WAAO;AAAA;AAAA,gBAEK,SAAS;AAAA,MACf,iBAAiB;AAAA,MACjB,CAAC,UAAU,IAAI,EAAE,GAAG;AAAA,MACpB,kBAAkB;AAAA,IAAA,CACnB,CAAC;AAAA;AAAA;AAAA,kDAGwC,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpD;AAAA,EAEmB,WAAW,SAAqC;AACjE,UAAM,WAAW,OAAO;AAQxB,2BAAuB,qBAAqB,KAAK,OAAO,KAAK,SAAS;AAAA,EACxE;AAAA,EAES,SAAS;AAChB,UAAM,YAAY,KAAK;AACvB,UAAM,gBAAgB,KAAK;AAC3B,UAAM,aAAa,KAAK,cAAc,iBAAiB;AACvD,UAAM,iBAAiB;AAAA,MACrB,KAAK;AAAA,MACL,KAAK;AAAA,IAAA;AAEP,UAAM,YAAY,wBAAwB,KAAK,OAAO,KAAK,SAAS;AAGpE,UAAM,OAAO,KAAK,MACd,KAAK,UACL,aACG,aAAa,MACd,mBAAmB,gBAAgB,aAAa;AAKtD,UAAM,YACJ,KAAK,OACL,cACA,CAAC,KAAK,eACN,mBAAmB,UACnB,iBAAiB,IACb,IACA,KAAK,IAAI,KAAK,YAAY,wBAAwB,IAAI,GAAG,CAAC;AAChE,UAAM,SAAS,YAAY,IAAI,IAAI,OAAO,SAAS,IAAI;AAOvD,UAAM,WAAW,aACZ,KAAK,iBAAiB,KACvB,KAAK,cACH,KAAK,eACL,KAAK,cAAc,KAAK,eAAe,KAAK,YAAY;AAE9D,UAAM,QAAQ;AAAA;AAAA,gBAEF,SAAS;AAAA,MACf,OAAO;AAAA,MACP,CAAC,SAAS,KAAK,OAAO,EAAE,GAAG;AAAA,MAC3B,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,MACvB,iBAAiB,KAAK;AAAA,MACtB,UAAU,KAAK;AAAA,MACf,aAAa,KAAK,cAAc;AAAA,MAChC,aAAa,KAAK,cAAc;AAAA,MAChC,GAAG,KAAK,mBAAA;AAAA,IAAmB,CAC5B,CAAC;AAAA,4BACkB,KAAK,OAAO;AAAA;AAAA,UAE9B,KAAK,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,oBAKP,SAAS;AAAA,0BACH,KAAK,MAAM;AAAA,yBACZ,KAAK,SAAS;AAAA,2BACZ,IAAI;AAAA;AAAA,cAEjB,SACE;AAAA,qBACK,MAAM;AAAA,qBAEX,OAAO,GAAG,IAAI;AAAA,cAChB,WAAW,2BAA2B,QAAQ,YAAY,OAAO;AAAA;AAAA,YAEnE,KAAK,YAAY,KAAK,kBAAkB,SAAS,IAAI,OAAO;AAAA;AAAA;AAAA;AAIpE,WAAO,mBAAmB,KAAK,SAAS,OAAO,KAAK;AAAA,EACtD;AAGF;AApSa,gBAmSK,SAAS,UAAU,cAAc;AAjSvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,gBAEe,WAAA,WAAA,CAAA;AAOA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GATb,gBASe,WAAA,SAAA,CAAA;AAOA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhBb,gBAgBe,WAAA,aAAA,CAAA;AAIA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApBb,gBAoBe,WAAA,QAAA,CAAA;AAOA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA3Bb,gBA2Be,WAAA,aAAA,CAAA;AAGC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA9Bd,gBA8BgB,WAAA,YAAA,CAAA;AAGD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjCb,gBAiCe,WAAA,UAAA,CAAA;AAIC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GArCd,gBAqCgB,WAAA,aAAA,CAAA;AAGA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAxCd,gBAwCgB,WAAA,WAAA,CAAA;AAMD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA9Cb,gBA8Ce,WAAA,kBAAA,CAAA;AAMA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApDb,gBAoDe,WAAA,aAAA,CAAA;AAMC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA1Dd,gBA0DgB,WAAA,eAAA,CAAA;AAGD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA7Db,gBA6De,WAAA,iBAAA,CAAA;AAGC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAhEd,gBAgEgB,WAAA,OAAA,CAAA;AAGD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnEb,gBAmEe,WAAA,WAAA,CAAA;AAGA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtEb,gBAsEe,WAAA,aAAA,CAAA;AAIA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA1Eb,gBA0Ee,WAAA,eAAA,CAAA;AAMA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAhFb,gBAgFe,WAAA,SAAA,CAAA;AAGC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAnFd,gBAmFgB,WAAA,YAAA,CAAA;AAGD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtFb,gBAsFe,WAAA,aAAA,CAAA;AAGT,gBAAA;AAAA,EAAhB,MAAA;AAAM,GAzFI,gBAyFM,WAAA,mBAAA,CAAA;AAzFN,kBAAN,gBAAA;AAAA,EADN,cAAc,mBAAmB;AAAA,GACrB,eAAA;"}
@@ -220,7 +220,7 @@ export declare class ObcCompass extends LitElement {
220
220
  priority: Priority;
221
221
  /** @availableWhen priority==enhanced */
222
222
  priorityElements: CompassPriorityElement[];
223
- /** Show compass NSEW labels and north arrow. */
223
+ /** Show compass NSEW labels. The north arrow is always shown, independent of this flag. */
224
224
  showLabels: boolean;
225
225
  /** When true, labels and north arrow are placed inside the outer ring. */
226
226
  tickmarksInside: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"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"}
@@ -204,7 +204,7 @@ let ObcCompass = class extends LitElement {
204
204
  .tickmarksInside=${this.tickmarksInside}
205
205
  .crosshairEnabled=${true}
206
206
  .crosshairCenterCutout=${this.hasCenterReadouts}
207
- .northArrow=${!frame.labelsHidden}
207
+ .northArrow=${true}
208
208
  .angleSetpoint=${this.headingSetpoint ?? void 0}
209
209
  .newAngleSetpoint=${this.newHeadingSetpoint}
210
210
  .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
@@ -1 +1 @@
1
- {"version":3,"file":"compass.js","sources":["../../../src/navigation-instruments/compass/compass.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.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};\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\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\n * `rateOfTurnDegreesPerMinute` (deg/min, the maritime / AIS convention).\n * Supports spinning dots (`rotType=\"dots\"`) — the dot animation is\n * amplified by `rotDotAnimationFactor` so small physical values still\n * read at a glance — and a banana-shaped arc bar (`rotType=\"bar\"`)\n * showing the rate of turn as an arc anchored at the current heading.\n * Bar extent is driven by the physical value only (gain is not applied).\n * Position on the outer 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 * - **Arrow styles**: The HDG and COG arrows each select their look via\n * `hdgArrowStyle` (`arrowHead` default, `needle`, `vector`, `beamLine`)\n * and `cogArrowStyle` (`arrowHead` default, `needle`, `vector`,\n * `velocityVector`).\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\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 `currentWindSpeedKnots` / `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 *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n /** The current heading of the vessel in degrees. */\n @property({type: Number}) heading = 0;\n /** The current course over ground in degrees. */\n @property({type: Number}) courseOverGround = 0;\n\n /** The set point for the heading in degrees. */\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /**\n * Indicates if the vessel is at the heading set point.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false\n */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /**\n * Enables automatic at heading set point calculation.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /**\n * The deadband for the heading set point in degrees.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true\n */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Indicates if the compass is being touched.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean}) touching: boolean = false;\n /** An array of angle advices for the compass. */\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n /**\n * The wind speed in knots.\n * @availableWhen windFromDirection!=null\n */\n @property({type: Number}) currentWindSpeedKnots: number | null = null;\n /**\n * The direction the wind is coming from in degrees.\n * @availableWhen currentWindSpeedKnots!=null\n */\n @property({type: Number}) windFromDirection: number | null = null;\n /**\n * The current speed, number of arrows.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /**\n * The direction the current is coming from in degrees.\n * @availableWhen currentSpeed!=null\n */\n @property({type: Number}) currentFromDirection: number | null = null;\n /**\n * The image of the vessel. Hidden while `centerReadouts` is non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`, `rot` →\n * `rateOfTurnDegreesPerMinute`, a dash when unset) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `arrowHead` (default), `needle`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle =\n HdgArrowStyle.arrowHead;\n /** COG arrow style: `arrowHead` (default), `needle`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle =\n CogArrowStyle.arrowHead;\n /**\n * Measured rate of turn in degrees per minute (positive = starboard).\n * Drives both the bar extent and (after multiplication by\n * `rotDotAnimationFactor`) the spinning dot animation.\n * When `undefined`, falls back to the deprecated `rotationsPerMinute`.\n */\n @property({type: Number}) rateOfTurnDegreesPerMinute: number | undefined;\n /**\n * Visual amplification applied only to the spinning dot animation\n * (not to the bar extent). Default `18` keeps the legacy visual feel\n * (≈1 rpm at 20°/min).\n * @availableWhen rotType==dots\n */\n @property({type: Number}) rotDotAnimationFactor: number = 18;\n /**\n * Legacy rate-of-turn input, in rotations per minute. When\n * `rateOfTurnDegreesPerMinute` is `undefined`, this value is used\n * (unconverted) as the fallback ROT, driving both the spinning dot ring\n * and the bar extent.\n * @deprecated Use `rateOfTurnDegreesPerMinute` (and optionally\n * `rotDotAnimationFactor`) instead. Takes effect only when\n * `rateOfTurnDegreesPerMinute` is `undefined`.\n */\n @property({type: Number}) rotationsPerMinute: number = 1;\n /** ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (a rate-of-turn arc anchored at the current heading, its length proportional to the rate of turn). */\n @property({type: String}) rotType: RotType = RotType.dots;\n /** ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring). */\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n /**\n * Bar-extent reference value in **degrees per minute**. The bar fills the\n * full ±`rotArcExtent` arc when the measured ROT equals ±`rotMaxValue`.\n * Default `60` aligns with ES-TRIN 2025/1 Art. 3.02.\n *\n * Note: prior to the introduction of `rateOfTurnDegreesPerMinute` this\n * property was interpreted in rotations per minute. The unit changed when\n * the physical ROT API was introduced.\n * @availableWhen rotType==bar\n */\n @property({type: Number}) rotMaxValue: number = 60;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n /** @availableWhen rotType==bar */\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 /** Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette. */\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\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 * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\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 /**\n * Resolved rate of turn in degrees per minute, used to compute the bar\n * extent. Prefers the new physical API; falls back to the deprecated\n * `rotationsPerMinute` so existing consumers keep their visuals during\n * the deprecation window.\n */\n private get _effectiveRotDegPerMin(): number {\n return this.rateOfTurnDegreesPerMinute ?? this.rotationsPerMinute;\n }\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n * Wind/current symbols at their default radius are covered by the base\n * padding of 72.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\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 readoutPriorityFor(source: CompassReadoutSource): Priority {\n switch (source) {\n case CompassReadoutSource.hdg:\n return this.priorityFor(CompassPriorityElement.hdg);\n case CompassReadoutSource.cog:\n return this.priorityFor(CompassPriorityElement.cog);\n case CompassReadoutSource.rot:\n return this.priorityFor(CompassPriorityElement.rot);\n }\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\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 frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${!frame.labelsHidden}\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=${this.hasCenterReadouts\n ? []\n : [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .windKnots=${this.currentWindSpeedKnots}\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._effectiveRotDegPerMin / (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 .rateOfTurnDegreesPerMinute=${this.rateOfTurnDegreesPerMinute}\n .rotDotAnimationFactor=${this.rotDotAnimationFactor}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n rateOfTurnDegreesPerMinute: this.rateOfTurnDegreesPerMinute,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\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, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.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};\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\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\n * `rateOfTurnDegreesPerMinute` (deg/min, the maritime / AIS convention).\n * Supports spinning dots (`rotType=\"dots\"`) — the dot animation is\n * amplified by `rotDotAnimationFactor` so small physical values still\n * read at a glance — and a banana-shaped arc bar (`rotType=\"bar\"`)\n * showing the rate of turn as an arc anchored at the current heading.\n * Bar extent is driven by the physical value only (gain is not applied).\n * Position on the outer 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 * - **Arrow styles**: The HDG and COG arrows each select their look via\n * `hdgArrowStyle` (`arrowHead` default, `needle`, `vector`, `beamLine`)\n * and `cogArrowStyle` (`arrowHead` default, `needle`, `vector`,\n * `velocityVector`).\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\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 `currentWindSpeedKnots` / `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 *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n /** The current heading of the vessel in degrees. */\n @property({type: Number}) heading = 0;\n /** The current course over ground in degrees. */\n @property({type: Number}) courseOverGround = 0;\n\n /** The set point for the heading in degrees. */\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /**\n * Indicates if the vessel is at the heading set point.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false\n */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /**\n * Enables automatic at heading set point calculation.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /**\n * The deadband for the heading set point in degrees.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true\n */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Indicates if the compass is being touched.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean}) touching: boolean = false;\n /** An array of angle advices for the compass. */\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n /**\n * The wind speed in knots.\n * @availableWhen windFromDirection!=null\n */\n @property({type: Number}) currentWindSpeedKnots: number | null = null;\n /**\n * The direction the wind is coming from in degrees.\n * @availableWhen currentWindSpeedKnots!=null\n */\n @property({type: Number}) windFromDirection: number | null = null;\n /**\n * The current speed, number of arrows.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /**\n * The direction the current is coming from in degrees.\n * @availableWhen currentSpeed!=null\n */\n @property({type: Number}) currentFromDirection: number | null = null;\n /**\n * The image of the vessel. Hidden while `centerReadouts` is non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`, `rot` →\n * `rateOfTurnDegreesPerMinute`, a dash when unset) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `arrowHead` (default), `needle`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle =\n HdgArrowStyle.arrowHead;\n /** COG arrow style: `arrowHead` (default), `needle`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle =\n CogArrowStyle.arrowHead;\n /**\n * Measured rate of turn in degrees per minute (positive = starboard).\n * Drives both the bar extent and (after multiplication by\n * `rotDotAnimationFactor`) the spinning dot animation.\n * When `undefined`, falls back to the deprecated `rotationsPerMinute`.\n */\n @property({type: Number}) rateOfTurnDegreesPerMinute: number | undefined;\n /**\n * Visual amplification applied only to the spinning dot animation\n * (not to the bar extent). Default `18` keeps the legacy visual feel\n * (≈1 rpm at 20°/min).\n * @availableWhen rotType==dots\n */\n @property({type: Number}) rotDotAnimationFactor: number = 18;\n /**\n * Legacy rate-of-turn input, in rotations per minute. When\n * `rateOfTurnDegreesPerMinute` is `undefined`, this value is used\n * (unconverted) as the fallback ROT, driving both the spinning dot ring\n * and the bar extent.\n * @deprecated Use `rateOfTurnDegreesPerMinute` (and optionally\n * `rotDotAnimationFactor`) instead. Takes effect only when\n * `rateOfTurnDegreesPerMinute` is `undefined`.\n */\n @property({type: Number}) rotationsPerMinute: number = 1;\n /** ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (a rate-of-turn arc anchored at the current heading, its length proportional to the rate of turn). */\n @property({type: String}) rotType: RotType = RotType.dots;\n /** ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring). */\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n /**\n * Bar-extent reference value in **degrees per minute**. The bar fills the\n * full ±`rotArcExtent` arc when the measured ROT equals ±`rotMaxValue`.\n * Default `60` aligns with ES-TRIN 2025/1 Art. 3.02.\n *\n * Note: prior to the introduction of `rateOfTurnDegreesPerMinute` this\n * property was interpreted in rotations per minute. The unit changed when\n * the physical ROT API was introduced.\n * @availableWhen rotType==bar\n */\n @property({type: Number}) rotMaxValue: number = 60;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n /** @availableWhen rotType==bar */\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 /** Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette. */\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: CompassPriorityElement[] = [CompassPriorityElement.hdg];\n /** Show compass NSEW labels. The north arrow is always shown, independent of this flag. */\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 * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\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 /**\n * Resolved rate of turn in degrees per minute, used to compute the bar\n * extent. Prefers the new physical API; falls back to the deprecated\n * `rotationsPerMinute` so existing consumers keep their visuals during\n * the deprecation window.\n */\n private get _effectiveRotDegPerMin(): number {\n return this.rateOfTurnDegreesPerMinute ?? this.rotationsPerMinute;\n }\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n * Wind/current symbols at their default radius are covered by the base\n * padding of 72.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\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 readoutPriorityFor(source: CompassReadoutSource): Priority {\n switch (source) {\n case CompassReadoutSource.hdg:\n return this.priorityFor(CompassPriorityElement.hdg);\n case CompassReadoutSource.cog:\n return this.priorityFor(CompassPriorityElement.cog);\n case CompassReadoutSource.rot:\n return this.priorityFor(CompassPriorityElement.rot);\n }\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\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 frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\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=${this.hasCenterReadouts\n ? []\n : [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .windKnots=${this.currentWindSpeedKnots}\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._effectiveRotDegPerMin / (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 .rateOfTurnDegreesPerMinute=${this.rateOfTurnDegreesPerMinute}\n .rotDotAnimationFactor=${this.rotDotAnimationFactor}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n rateOfTurnDegreesPerMinute: this.rateOfTurnDegreesPerMinute,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass': ObcCompass;\n }\n}\n"],"names":["CompassDirection","CompassPriorityElement"],"mappings":"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"}
@@ -32,6 +32,9 @@ export declare function clampCurrentSpeed(value: number | null): number | null;
32
32
  * the enhanced (blue) palette.
33
33
  * - **Vessel image**: configurable silhouette rotating with
34
34
  * `vesselHeadingDeg` (vessel type).
35
+ * - **Pattern toggle & wave tuning**: `hasPattern` switches the band pattern
36
+ * off; `waveLength`, `waveHeight` and `waveSpeed` tune the band spacing,
37
+ * intensity and drift motion.
35
38
  *
36
39
  * ## Usage Guidelines
37
40
  *
@@ -64,6 +67,28 @@ export declare class ObcCurrent extends LitElement {
64
67
  currentFromDirection: number | null;
65
68
  /** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */
66
69
  priority: Priority;
70
+ /**
71
+ * Show the force-graphics band pattern behind the watch face.
72
+ * @availableWhen currentFromDirection!=null
73
+ */
74
+ hasPattern: boolean;
75
+ /**
76
+ * Wavelength of the pattern bands as a multiplier on the design spacing
77
+ * (1 = design, 0.5 = twice as dense).
78
+ * @availableWhen hasPattern==true && currentFromDirection!=null
79
+ */
80
+ waveLength: number;
81
+ /**
82
+ * Wave intensity: the peak opacity the pattern bands fade up to (0–1).
83
+ * @availableWhen hasPattern==true && currentFromDirection!=null
84
+ */
85
+ waveHeight: number;
86
+ /**
87
+ * Drift speed of the pattern in wavelengths per second, moving with the
88
+ * flow (negative drifts against it); 0 keeps the pattern static.
89
+ * @availableWhen hasPattern==true && currentFromDirection!=null
90
+ */
91
+ waveSpeed: number;
67
92
  /**
68
93
  * The image of the vessel.
69
94
  * @availableWhen type==vessel
@@ -1 +1 @@
1
- {"version":3,"file":"current.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/current/current.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EACL,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGrC,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;AASD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,2FAA2F;IACjE,IAAI,EAAE,WAAW,CAAsB;IACjE;;;;OAIG;IACuB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7D,2DAA2D;IACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACrE,wGAAwG;IAC9E,QAAQ,EAAE,QAAQ,CAAoB;IAChE;;;OAGG;IACuB,WAAW,EAAE,WAAW,CAA0B;IAC5E;;;OAGG;IACuB,gBAAgB,EAAE,MAAM,CAAK;IAEvD,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAEQ,MAAM;IAuCf,OAAO,CAAC,kBAAkB;IAoB1B,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"current.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/current/current.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EACL,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGrC,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;AAeD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,2FAA2F;IACjE,IAAI,EAAE,WAAW,CAAsB;IACjE;;;;OAIG;IACuB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7D,2DAA2D;IACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACrE,wGAAwG;IAC9E,QAAQ,EAAE,QAAQ,CAAoB;IAChE;;;OAGG;IAC0C,UAAU,UAAQ;IAC/D;;;;OAIG;IACuB,UAAU,SAAK;IACzC;;;OAGG;IACuB,UAAU,SAAK;IACzC;;;;OAIG;IACuB,SAAS,SAAK;IACxC;;;OAGG;IACuB,WAAW,EAAE,WAAW,CAA0B;IAC5E;;;OAGG;IACuB,gBAAgB,EAAE,MAAM,CAAK;IAEvD,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAEQ,MAAM;IAuCf,OAAO,CAAC,kBAAkB;IAuB1B,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
@@ -1,7 +1,7 @@
1
1
  import { unsafeCSS, LitElement, html, nothing } from "lit";
2
2
  import { property } from "lit/decorators.js";
3
3
  import compentStyle from "./current.css.js";
4
- import { WatchCircleType, innerRingRadiusFor } from "../watch/watch.js";
4
+ import { innerRingRadiusFor, WatchCircleType } from "../watch/watch.js";
5
5
  import { renderCurrentForcePattern } from "../watch/force-pattern.js";
6
6
  import { Priority } from "../types.js";
7
7
  import { customElement } from "../../decorator.js";
@@ -23,7 +23,9 @@ var CurrentType = /* @__PURE__ */ ((CurrentType2) => {
23
23
  })(CurrentType || {});
24
24
  const CURRENT_PATTERN_SCALE_VESSEL = 1.39;
25
25
  const CURRENT_PATTERN_SCALE_DIRECTION = 2;
26
- const CURRENT_ICON_PERIPHERY_RADIUS = 116;
26
+ const CURRENT_ICON_PERIPHERY_RADIUS = innerRingRadiusFor(
27
+ WatchCircleType.double
28
+ );
27
29
  const CURRENT_DIRECTION_ICON_SCALE = 7;
28
30
  function clampCurrentSpeed(value) {
29
31
  if (value == null || !Number.isFinite(value)) {
@@ -38,6 +40,10 @@ let ObcCurrent = class extends LitElement {
38
40
  this.currentSpeed = null;
39
41
  this.currentFromDirection = null;
40
42
  this.priority = Priority.regular;
43
+ this.hasPattern = true;
44
+ this.waveLength = 1;
45
+ this.waveHeight = 1;
46
+ this.waveSpeed = 0;
41
47
  this.vesselImage = VesselImage.genericTop;
42
48
  this.vesselHeadingDeg = 0;
43
49
  }
@@ -80,7 +86,7 @@ let ObcCurrent = class extends LitElement {
80
86
  `;
81
87
  }
82
88
  renderForcePattern(watchCircleType) {
83
- if (this.currentFromDirection == null) {
89
+ if (!this.hasPattern || this.currentFromDirection == null) {
84
90
  return nothing;
85
91
  }
86
92
  return html`
@@ -89,7 +95,10 @@ let ObcCurrent = class extends LitElement {
89
95
  fromDirectionDeg: this.currentFromDirection,
90
96
  radius: innerRingRadiusFor(watchCircleType),
91
97
  patternScale: this.isVesselType ? CURRENT_PATTERN_SCALE_VESSEL : CURRENT_PATTERN_SCALE_DIRECTION,
92
- color: this.enhanced ? "var(--instrument-enhanced-tertiary-color)" : void 0
98
+ color: this.enhanced ? "var(--instrument-enhanced-tertiary-color)" : void 0,
99
+ waveLength: this.waveLength,
100
+ waveHeight: this.waveHeight,
101
+ waveSpeed: this.waveSpeed
93
102
  })}
94
103
  </svg>
95
104
  `;
@@ -108,6 +117,18 @@ __decorateClass([
108
117
  __decorateClass([
109
118
  property({ type: String })
110
119
  ], ObcCurrent.prototype, "priority", 2);
120
+ __decorateClass([
121
+ property({ type: Boolean, attribute: false })
122
+ ], ObcCurrent.prototype, "hasPattern", 2);
123
+ __decorateClass([
124
+ property({ type: Number })
125
+ ], ObcCurrent.prototype, "waveLength", 2);
126
+ __decorateClass([
127
+ property({ type: Number })
128
+ ], ObcCurrent.prototype, "waveHeight", 2);
129
+ __decorateClass([
130
+ property({ type: Number })
131
+ ], ObcCurrent.prototype, "waveSpeed", 2);
111
132
  __decorateClass([
112
133
  property({ type: String })
113
134
  ], ObcCurrent.prototype, "vesselImage", 2);
@@ -1 +1 @@
1
- {"version":3,"file":"current.js","sources":["../../../src/navigation-instruments/current/current.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './current.css?inline';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n innerRingRadiusFor,\n} from '../watch/watch.js';\nimport {renderCurrentForcePattern} from '../watch/force-pattern.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum CurrentType {\n vessel = 'vessel',\n direction = 'direction',\n}\n\nconst CURRENT_PATTERN_SCALE_VESSEL = 1.39;\nconst CURRENT_PATTERN_SCALE_DIRECTION = 2.0;\n/** Chevron-tip anchor radius for the peripheral icon (vessel type), from Figma. */\nconst CURRENT_ICON_PERIPHERY_RADIUS = 116;\n/** Scale of the centered 24-unit chevron glyph (direction type), from Figma (168/24). */\nconst CURRENT_DIRECTION_ICON_SCALE = 7;\n\n/**\n * Round a current speed to the nearest chevron bucket (`current-0` …\n * `current-4` icons) and clamp it into that range. Non-finite input maps to\n * `null` (no icon).\n */\nexport function clampCurrentSpeed(value: number | null): number | null {\n if (value == null || !Number.isFinite(value)) {\n return null;\n }\n return Math.min(4, Math.max(0, Math.round(value)));\n}\n\n/**\n * `<obc-current>` – Water-current instrument with direction chevrons and a\n * force-graphics band pattern.\n *\n * Renders the current's from-direction and strength on a circular watch\n * face. Two layouts are available via `type`: `vessel` (default) shows a\n * vessel silhouette on a double-ring track face with a chevron icon at the\n * periphery pointing with the flow; `direction` shows a single-ring face\n * with a large centered chevron icon. In both, a soft band pattern fills the\n * face, rotated perpendicular to the flow.\n *\n * ## Features\n *\n * - **Types**: `vessel` (track face + vessel + peripheral icon) or\n * `direction` (single ring + large centered icon) via `type`.\n * - **Strength buckets**: `currentSpeed` selects the chevron icon\n * (`0`–`4` = number of chevrons); values are rounded and clamped.\n * - **Color priority**: `priority=enhanced` switches the pattern and icon to\n * the enhanced (blue) palette.\n * - **Vessel image**: configurable silhouette rotating with\n * `vesselHeadingDeg` (vessel type).\n *\n * ## Usage Guidelines\n *\n * Set `currentSpeed` and `currentFromDirection` to the sensor values. Use\n * `obc-wind` for the analogous wind instrument; use `obc-compass` when the\n * current indicator should overlay a full compass.\n *\n * ## Example\n *\n * ```html\n * <obc-current\n * currentSpeed=\"3\"\n * currentFromDirection=\"330\"\n * vesselHeadingDeg=\"15\"\n * ></obc-current>\n * ```\n *\n * @experimental\n */\n@customElement('obc-current')\nexport class ObcCurrent extends LitElement {\n /** Layout type: `vessel` (track face with vessel) or `direction` (large centered icon). */\n @property({type: String}) type: CurrentType = CurrentType.vessel;\n /**\n * The current strength as a chevron bucket (0–4 = number of chevrons);\n * rounded and clamped. `null` hides the icon.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /** The direction the current is coming from in degrees. */\n @property({type: Number}) currentFromDirection: number | null = null;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */\n @property({type: String}) priority: Priority = Priority.regular;\n /**\n * The image of the vessel.\n * @availableWhen type==vessel\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Vessel heading in degrees.\n * @availableWhen type==vessel\n */\n @property({type: Number}) vesselHeadingDeg: number = 0;\n\n private get isVesselType(): boolean {\n return this.type !== CurrentType.direction;\n }\n\n private get enhanced(): boolean {\n return this.priority === Priority.enhanced;\n }\n\n override render() {\n const isVessel = this.isVesselType;\n const watchCircleType = isVessel\n ? WatchCircleType.double\n : WatchCircleType.single;\n const vessels = isVessel\n ? [\n {\n size: VesselImageSize.medium,\n transform: `rotate(${this.vesselHeadingDeg}deg)`,\n vesselImage: this.vesselImage,\n },\n ]\n : [];\n return html`\n <div class=\"wrapper\">\n ${this.renderForcePattern(watchCircleType)}\n <obc-watch\n .watchCircleType=${watchCircleType}\n .priority=${this.priority}\n .vessels=${vessels}\n .current=${clampCurrentSpeed(this.currentSpeed)}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentSymbolRadius=${CURRENT_ICON_PERIPHERY_RADIUS}\n .currentIconCentered=${!isVessel}\n .scaleCurrentIcon=${isVessel ? 1 : CURRENT_DIRECTION_ICON_SCALE}\n .currentColor=${this.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined}\n .showLabels=${true}\n .insideLabelsFlush=${true}\n crosshairEnabled\n northArrow\n tickmarksInside\n ></obc-watch>\n </div>\n `;\n }\n\n private renderForcePattern(watchCircleType: WatchCircleType) {\n if (this.currentFromDirection == null) {\n return nothing;\n }\n return html`\n <svg width=\"100%\" height=\"100%\" viewBox=\"-200 -200 400 400\">\n ${renderCurrentForcePattern({\n fromDirectionDeg: this.currentFromDirection,\n radius: innerRingRadiusFor(watchCircleType),\n patternScale: this.isVesselType\n ? CURRENT_PATTERN_SCALE_VESSEL\n : CURRENT_PATTERN_SCALE_DIRECTION,\n color: this.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : undefined,\n })}\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-current': ObcCurrent;\n }\n}\n"],"names":["CurrentType"],"mappings":"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"}
1
+ {"version":3,"file":"current.js","sources":["../../../src/navigation-instruments/current/current.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './current.css?inline';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n innerRingRadiusFor,\n} from '../watch/watch.js';\nimport {renderCurrentForcePattern} from '../watch/force-pattern.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum CurrentType {\n vessel = 'vessel',\n direction = 'direction',\n}\n\nconst CURRENT_PATTERN_SCALE_VESSEL = 1.39;\nconst CURRENT_PATTERN_SCALE_DIRECTION = 2.0;\n/**\n * Chevron-tip anchor radius for the peripheral icon (vessel type): the tip\n * sits on the track band's inner edge (112), so the 48-unit glyph box fills\n * the band (112–160) exactly, per the OpenBridge 6.1 design.\n */\nconst CURRENT_ICON_PERIPHERY_RADIUS = innerRingRadiusFor(\n WatchCircleType.double\n);\n/** Scale of the centered 24-unit chevron glyph (direction type), from Figma (168/24). */\nconst CURRENT_DIRECTION_ICON_SCALE = 7;\n\n/**\n * Round a current speed to the nearest chevron bucket (`current-0` …\n * `current-4` icons) and clamp it into that range. Non-finite input maps to\n * `null` (no icon).\n */\nexport function clampCurrentSpeed(value: number | null): number | null {\n if (value == null || !Number.isFinite(value)) {\n return null;\n }\n return Math.min(4, Math.max(0, Math.round(value)));\n}\n\n/**\n * `<obc-current>` – Water-current instrument with direction chevrons and a\n * force-graphics band pattern.\n *\n * Renders the current's from-direction and strength on a circular watch\n * face. Two layouts are available via `type`: `vessel` (default) shows a\n * vessel silhouette on a double-ring track face with a chevron icon at the\n * periphery pointing with the flow; `direction` shows a single-ring face\n * with a large centered chevron icon. In both, a soft band pattern fills the\n * face, rotated perpendicular to the flow.\n *\n * ## Features\n *\n * - **Types**: `vessel` (track face + vessel + peripheral icon) or\n * `direction` (single ring + large centered icon) via `type`.\n * - **Strength buckets**: `currentSpeed` selects the chevron icon\n * (`0`–`4` = number of chevrons); values are rounded and clamped.\n * - **Color priority**: `priority=enhanced` switches the pattern and icon to\n * the enhanced (blue) palette.\n * - **Vessel image**: configurable silhouette rotating with\n * `vesselHeadingDeg` (vessel type).\n * - **Pattern toggle & wave tuning**: `hasPattern` switches the band pattern\n * off; `waveLength`, `waveHeight` and `waveSpeed` tune the band spacing,\n * intensity and drift motion.\n *\n * ## Usage Guidelines\n *\n * Set `currentSpeed` and `currentFromDirection` to the sensor values. Use\n * `obc-wind` for the analogous wind instrument; use `obc-compass` when the\n * current indicator should overlay a full compass.\n *\n * ## Example\n *\n * ```html\n * <obc-current\n * currentSpeed=\"3\"\n * currentFromDirection=\"330\"\n * vesselHeadingDeg=\"15\"\n * ></obc-current>\n * ```\n *\n * @experimental\n */\n@customElement('obc-current')\nexport class ObcCurrent extends LitElement {\n /** Layout type: `vessel` (track face with vessel) or `direction` (large centered icon). */\n @property({type: String}) type: CurrentType = CurrentType.vessel;\n /**\n * The current strength as a chevron bucket (0–4 = number of chevrons);\n * rounded and clamped. `null` hides the icon.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /** The direction the current is coming from in degrees. */\n @property({type: Number}) currentFromDirection: number | null = null;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */\n @property({type: String}) priority: Priority = Priority.regular;\n /**\n * Show the force-graphics band pattern behind the watch face.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Boolean, attribute: false}) hasPattern = true;\n /**\n * Wavelength of the pattern bands as a multiplier on the design spacing\n * (1 = design, 0.5 = twice as dense).\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveLength = 1;\n /**\n * Wave intensity: the peak opacity the pattern bands fade up to (0–1).\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveHeight = 1;\n /**\n * Drift speed of the pattern in wavelengths per second, moving with the\n * flow (negative drifts against it); 0 keeps the pattern static.\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveSpeed = 0;\n /**\n * The image of the vessel.\n * @availableWhen type==vessel\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Vessel heading in degrees.\n * @availableWhen type==vessel\n */\n @property({type: Number}) vesselHeadingDeg: number = 0;\n\n private get isVesselType(): boolean {\n return this.type !== CurrentType.direction;\n }\n\n private get enhanced(): boolean {\n return this.priority === Priority.enhanced;\n }\n\n override render() {\n const isVessel = this.isVesselType;\n const watchCircleType = isVessel\n ? WatchCircleType.double\n : WatchCircleType.single;\n const vessels = isVessel\n ? [\n {\n size: VesselImageSize.medium,\n transform: `rotate(${this.vesselHeadingDeg}deg)`,\n vesselImage: this.vesselImage,\n },\n ]\n : [];\n return html`\n <div class=\"wrapper\">\n ${this.renderForcePattern(watchCircleType)}\n <obc-watch\n .watchCircleType=${watchCircleType}\n .priority=${this.priority}\n .vessels=${vessels}\n .current=${clampCurrentSpeed(this.currentSpeed)}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentSymbolRadius=${CURRENT_ICON_PERIPHERY_RADIUS}\n .currentIconCentered=${!isVessel}\n .scaleCurrentIcon=${isVessel ? 1 : CURRENT_DIRECTION_ICON_SCALE}\n .currentColor=${this.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined}\n .showLabels=${true}\n .insideLabelsFlush=${true}\n crosshairEnabled\n northArrow\n tickmarksInside\n ></obc-watch>\n </div>\n `;\n }\n\n private renderForcePattern(watchCircleType: WatchCircleType) {\n if (!this.hasPattern || this.currentFromDirection == null) {\n return nothing;\n }\n return html`\n <svg width=\"100%\" height=\"100%\" viewBox=\"-200 -200 400 400\">\n ${renderCurrentForcePattern({\n fromDirectionDeg: this.currentFromDirection,\n radius: innerRingRadiusFor(watchCircleType),\n patternScale: this.isVesselType\n ? CURRENT_PATTERN_SCALE_VESSEL\n : CURRENT_PATTERN_SCALE_DIRECTION,\n color: this.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : undefined,\n waveLength: this.waveLength,\n waveHeight: this.waveHeight,\n waveSpeed: this.waveSpeed,\n })}\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-current': ObcCurrent;\n }\n}\n"],"names":["CurrentType"],"mappings":"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"}
@@ -181,7 +181,7 @@ let ObcHeading = class extends LitElement {
181
181
  .tickmarksInside=${this.tickmarksInside}
182
182
  .crosshairEnabled=${true}
183
183
  .crosshairCenterCutout=${this.hasCenterReadouts}
184
- .northArrow=${!frame.labelsHidden}
184
+ .northArrow=${true}
185
185
  .angleSetpoint=${this.headingSetpoint ?? void 0}
186
186
  .newAngleSetpoint=${this.newHeadingSetpoint}
187
187
  .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
@@ -1 +1 @@
1
- {"version":3,"file":"heading.js","sources":["../../../src/navigation-instruments/heading/heading.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {VesselImage, VesselImageSize, WatchCircleType} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum HeadingPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n}\n\n/**\n * `<obc-heading>` – Heading instrument with HDG/COG arrows over a single-ring\n * watch face, with optional vessel silhouette and center readouts.\n *\n * Renders a circular instrument that displays heading (HDG) and course over\n * ground (COG) as rotating arrows. It supports a heading setpoint with auto\n * at-setpoint detection, advice zones, north-up/heading-up/course-up\n * orientation, an optional vessel image, and center readouts replacing the\n * vessel.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two arrows overlay the watch face, rotating\n * independently; their look is selected per arrow via `hdgArrowStyle`\n * (`needle` default, `arrowHead`, `vector`, `beamLine`) and\n * `cogArrowStyle` (`needle` default, `arrowHead`, `vector`,\n * `velocityVector`).\n * - **Vessel image**: Optional vessel silhouette via `vesselImage`\n * (hidden by default), centered and rotating with heading.\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\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 * - **Color priority**: Set `priority` to `Priority.enhanced` and select\n * the accented elements via `priorityElements`.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values in\n * degrees.\n * - Use `obc-compass` instead when rate-of-turn, wind or current overlays\n * are needed — this instrument is the reduced heading-focused variant.\n *\n * ## Example\n *\n * ```html\n * <obc-heading\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * ></obc-heading>\n * ```\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-heading')\nexport class ObcHeading extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: HeadingPriorityElement[] = [HeadingPriorityElement.hdg];\n /**\n * The vessel silhouette shown in the center, rotating with heading. When\n * unset (default) no vessel is shown; hidden while `centerReadouts` is\n * non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage | undefined;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`; `rot` has no\n * input on this instrument and renders a dash) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `needle` (default), `arrowHead`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle = HdgArrowStyle.needle;\n /** COG arrow style: `needle` (default), `arrowHead`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle = CogArrowStyle.needle;\n /** Show compass NSEW labels. */\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 * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\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 /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\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: HeadingPriorityElement): 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 readoutPriorityFor(source: CompassReadoutSource): Priority {\n if (source === CompassReadoutSource.hdg) {\n return this.priorityFor(HeadingPriorityElement.hdg);\n }\n if (source === CompassReadoutSource.cog) {\n return this.priorityFor(HeadingPriorityElement.cog);\n }\n return Priority.regular;\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n /**\n * The face gains the double-band ring while center content (vessel or\n * readouts) is shown, per the design's vessel/center-label faces.\n */\n private get watchCircleType(): WatchCircleType {\n return this.vesselImage !== undefined || this.hasCenterReadouts\n ? WatchCircleType.double\n : WatchCircleType.single;\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 frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .watchCircleType=${this.watchCircleType}\n .vessels=${this.vesselImage !== undefined && !this.hasCenterReadouts\n ? [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]\n : []}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${!frame.labelsHidden}\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 .rotation=${this.getRotation()}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-heading': ObcHeading;\n }\n}\n"],"names":["CompassDirection","HeadingPriorityElement"],"mappings":"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"}
1
+ {"version":3,"file":"heading.js","sources":["../../../src/navigation-instruments/heading/heading.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {VesselImage, VesselImageSize, WatchCircleType} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum HeadingPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n}\n\n/**\n * `<obc-heading>` – Heading instrument with HDG/COG arrows over a single-ring\n * watch face, with optional vessel silhouette and center readouts.\n *\n * Renders a circular instrument that displays heading (HDG) and course over\n * ground (COG) as rotating arrows. It supports a heading setpoint with auto\n * at-setpoint detection, advice zones, north-up/heading-up/course-up\n * orientation, an optional vessel image, and center readouts replacing the\n * vessel.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two arrows overlay the watch face, rotating\n * independently; their look is selected per arrow via `hdgArrowStyle`\n * (`needle` default, `arrowHead`, `vector`, `beamLine`) and\n * `cogArrowStyle` (`needle` default, `arrowHead`, `vector`,\n * `velocityVector`).\n * - **Vessel image**: Optional vessel silhouette via `vesselImage`\n * (hidden by default), centered and rotating with heading.\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\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 * - **Color priority**: Set `priority` to `Priority.enhanced` and select\n * the accented elements via `priorityElements`.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values in\n * degrees.\n * - Use `obc-compass` instead when rate-of-turn, wind or current overlays\n * are needed — this instrument is the reduced heading-focused variant.\n *\n * ## Example\n *\n * ```html\n * <obc-heading\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * ></obc-heading>\n * ```\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-heading')\nexport class ObcHeading extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: HeadingPriorityElement[] = [HeadingPriorityElement.hdg];\n /**\n * The vessel silhouette shown in the center, rotating with heading. When\n * unset (default) no vessel is shown; hidden while `centerReadouts` is\n * non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage | undefined;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`; `rot` has no\n * input on this instrument and renders a dash) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `needle` (default), `arrowHead`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle = HdgArrowStyle.needle;\n /** COG arrow style: `needle` (default), `arrowHead`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle = CogArrowStyle.needle;\n /** Show compass NSEW labels. */\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 * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\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 /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\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: HeadingPriorityElement): 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 readoutPriorityFor(source: CompassReadoutSource): Priority {\n if (source === CompassReadoutSource.hdg) {\n return this.priorityFor(HeadingPriorityElement.hdg);\n }\n if (source === CompassReadoutSource.cog) {\n return this.priorityFor(HeadingPriorityElement.cog);\n }\n return Priority.regular;\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n /**\n * The face gains the double-band ring while center content (vessel or\n * readouts) is shown, per the design's vessel/center-label faces.\n */\n private get watchCircleType(): WatchCircleType {\n return this.vesselImage !== undefined || this.hasCenterReadouts\n ? WatchCircleType.double\n : WatchCircleType.single;\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 frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .watchCircleType=${this.watchCircleType}\n .vessels=${this.vesselImage !== undefined && !this.hasCenterReadouts\n ? [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]\n : []}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\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 .rotation=${this.getRotation()}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-heading': ObcHeading;\n }\n}\n"],"names":["CompassDirection","HeadingPriorityElement"],"mappings":"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"}
@@ -122,6 +122,12 @@ export declare class ObcPitchRollHeave extends LitElement {
122
122
  * `obc-watch` renders its crosshair after the bands, i.e. on top of them.
123
123
  * Drawing it here puts it under the watch layer, so the bands and the heave
124
124
  * column mask it naturally.
125
+ *
126
+ * In `single-scale` nothing frames the segment above the vessel (the other
127
+ * three arms end under the pitch band, roll band and heave column), so the
128
+ * vertical arm stops at the centre instead of continuing upward. In
129
+ * `dual-scale` the top roll band gives it a natural endpoint, so the full
130
+ * arm is kept.
125
131
  */
126
132
  private renderCrosshair;
127
133
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pitch-roll-heave.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll-heave/pitch-roll-heave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkD,MAAM,KAAK,CAAC;AAEhF,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAgBrC,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,mDAAmD,CAAC;AAE3D,oBAAY,qBAAqB;IAC/B,2EAA2E;IAC3E,WAAW,iBAAiB;IAC5B,8DAA8D;IAC9D,SAAS,eAAe;CACzB;AAED,oBAAY,6BAA6B;IACvC,KAAK,UAAU;IACf,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AA2ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,IAAI,EAAE,qBAAqB,CACjB;IAEV,KAAK,SAAK;IACV,IAAI,SAAK;IACT,KAAK,SAAK;IACV,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,UAAU,SAAK;IACf,UAAU,SAAK;IACf,aAAa,SAAK;IAClB,aAAa,SAAK;IAC5C,gFAAgF;IACtD,UAAU,SAAM;IAE1C;;;;OAIG;IACuB,aAAa,SAAM;IAC7C,8CAA8C;IACpB,YAAY,SAAM;IACjB,YAAY,UAAS;IAEhD;;;;;OAKG;IACwB,UAAU,UAAS;IAC9C,sCAAsC;IACZ,UAAU,SAAW;IAC/C,sCAAsC;IACZ,SAAS,SAAU;IAC7C,sCAAsC;IACZ,UAAU,SAAW;IAC/C;;;OAGG;IACuB,IAAI,SAAS;IACvC;;;OAGG;IACuB,SAAS,SAAO;IAC1C,sCAAsC;IACZ,cAAc,SAAK;IAE7C,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,cAAc,SAAK;IAEnB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,CAAa;IACxE,+CAA+C;IACpB,kBAAkB,UAAS;IACtD,8CAA8C;IACnB,iBAAiB,UAAS;IAC5B,WAAW,EAAE,YAAY,EAAE,CAAM;IAEhC,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,6BAA6B,EAAE,CAI/C;IAEF,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,KAAK,wBAAwB,GAKnC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,8EAA8E;IAC9E,OAAO,KAAK,YAAY,GAEvB;IAED;;;OAGG;IACH,OAAO,KAAK,sBAAsB,GAKjC;IAED;;;;OAIG;IACH,OAAO,KAAK,qBAAqB,GAIhC;IAEQ,MAAM;IAuEf;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,KAAK,YAAY,GAWvB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,UAAU;IA2IlB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA4GxB,uEAAuE;IACvE,OAAO,CAAC,UAAU;IA4BlB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAqGvB,OAAO,CAAC,OAAO;IAqCf,OAAgB,MAAM,4BA2BpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}
1
+ {"version":3,"file":"pitch-roll-heave.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll-heave/pitch-roll-heave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkD,MAAM,KAAK,CAAC;AAEhF,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAgBrC,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,mDAAmD,CAAC;AAE3D,oBAAY,qBAAqB;IAC/B,2EAA2E;IAC3E,WAAW,iBAAiB;IAC5B,8DAA8D;IAC9D,SAAS,eAAe;CACzB;AAED,oBAAY,6BAA6B;IACvC,KAAK,UAAU;IACf,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AA2ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,IAAI,EAAE,qBAAqB,CACjB;IAEV,KAAK,SAAK;IACV,IAAI,SAAK;IACT,KAAK,SAAK;IACV,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,UAAU,SAAK;IACf,UAAU,SAAK;IACf,aAAa,SAAK;IAClB,aAAa,SAAK;IAC5C,gFAAgF;IACtD,UAAU,SAAM;IAE1C;;;;OAIG;IACuB,aAAa,SAAM;IAC7C,8CAA8C;IACpB,YAAY,SAAM;IACjB,YAAY,UAAS;IAEhD;;;;;OAKG;IACwB,UAAU,UAAS;IAC9C,sCAAsC;IACZ,UAAU,SAAW;IAC/C,sCAAsC;IACZ,SAAS,SAAU;IAC7C,sCAAsC;IACZ,UAAU,SAAW;IAC/C;;;OAGG;IACuB,IAAI,SAAS;IACvC;;;OAGG;IACuB,SAAS,SAAO;IAC1C,sCAAsC;IACZ,cAAc,SAAK;IAE7C,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,cAAc,SAAK;IAEnB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,CAAa;IACxE,+CAA+C;IACpB,kBAAkB,UAAS;IACtD,8CAA8C;IACnB,iBAAiB,UAAS;IAC5B,WAAW,EAAE,YAAY,EAAE,CAAM;IAEhC,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,6BAA6B,EAAE,CAI/C;IAEF,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,KAAK,wBAAwB,GAKnC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,8EAA8E;IAC9E,OAAO,KAAK,YAAY,GAEvB;IAED;;;OAGG;IACH,OAAO,KAAK,sBAAsB,GAKjC;IAED;;;;OAIG;IACH,OAAO,KAAK,qBAAqB,GAIhC;IAEQ,MAAM;IAuEf;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IAiBvB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,KAAK,YAAY,GAWvB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,UAAU;IA2IlB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA4GxB,uEAAuE;IACvE,OAAO,CAAC,UAAU;IA4BlB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAqGvB,OAAO,CAAC,OAAO;IAqCf,OAAgB,MAAM,4BA2BpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}