@oicl/openbridge-webcomponents 2.0.0-next.102 → 2.0.0-next.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/openbridge-webcomponents.bundle.js +583 -145
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +338 -8
- package/dist/building-blocks/instrument-radial/instrument-radial.d.ts +22 -2
- package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
- package/dist/building-blocks/instrument-radial/instrument-radial.js +61 -37
- package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
- package/dist/components/modal-window/modal-window.css.js +4 -2
- package/dist/components/modal-window/modal-window.css.js.map +1 -1
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts +14 -0
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts.map +1 -1
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js +30 -11
- package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js.map +1 -1
- package/dist/navigation-instruments/compass/compass.d.ts +21 -1
- package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
- package/dist/navigation-instruments/compass/compass.js +36 -16
- package/dist/navigation-instruments/compass/compass.js.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js +34 -2
- package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts +15 -0
- package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts.map +1 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.js +35 -1
- package/dist/navigation-instruments/gauge-radial/gauge-radial.js.map +1 -1
- package/dist/navigation-instruments/heading/heading.d.ts +19 -1
- package/dist/navigation-instruments/heading/heading.d.ts.map +1 -1
- package/dist/navigation-instruments/heading/heading.js +34 -16
- package/dist/navigation-instruments/heading/heading.js.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.d.ts +15 -2
- package/dist/navigation-instruments/rudder/rudder.d.ts.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.js +36 -26
- package/dist/navigation-instruments/rudder/rudder.js.map +1 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts +15 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts.map +1 -1
- package/dist/navigation-instruments/speed-gauge/speed-gauge.js +31 -3
- package/dist/navigation-instruments/speed-gauge/speed-gauge.js.map +1 -1
- package/dist/navigation-instruments/watch/watch.d.ts +29 -1
- package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/watch.js +52 -38
- package/dist/navigation-instruments/watch/watch.js.map +1 -1
- package/dist/svghelpers/radial-frame.d.ts +122 -0
- package/dist/svghelpers/radial-frame.d.ts.map +1 -0
- package/dist/svghelpers/radial-frame.js +259 -0
- package/dist/svghelpers/radial-frame.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { LitElement, nothing, html, svg, css } from "lit";
|
|
2
2
|
import { property } from "lit/decorators.js";
|
|
3
|
+
import { ResizeController } from "@lit-labs/observers/resize-controller.js";
|
|
4
|
+
import { observeInnerBox, applyPinnedHostSize, computeRadialFrame, measureContainerPx, estimateLabelWidthPx } from "../../svghelpers/radial-frame.js";
|
|
3
5
|
import { TickmarkStyle, TickmarkType } from "../watch/tickmark.js";
|
|
4
6
|
import { WatchCircleType } from "../watch/watch.js";
|
|
5
7
|
import { AdviceState } from "../watch/advice.js";
|
|
@@ -40,8 +42,22 @@ let ObcSpeedGauge = class extends SetpointMixin(LitElement) {
|
|
|
40
42
|
this.label = "STW";
|
|
41
43
|
this.unit = "KN";
|
|
42
44
|
this.fractionDigits = 1;
|
|
45
|
+
this._hostSizePinned = false;
|
|
46
|
+
this._resizeController = new ResizeController(this, {});
|
|
43
47
|
this.maxAngle = 180 - 45;
|
|
44
48
|
}
|
|
49
|
+
firstUpdated(changed) {
|
|
50
|
+
super.firstUpdated(changed);
|
|
51
|
+
observeInnerBox(this._resizeController, this.renderRoot);
|
|
52
|
+
}
|
|
53
|
+
updated(changed) {
|
|
54
|
+
super.updated(changed);
|
|
55
|
+
this._hostSizePinned = applyPinnedHostSize(
|
|
56
|
+
this,
|
|
57
|
+
this._frame,
|
|
58
|
+
this._hostSizePinned
|
|
59
|
+
);
|
|
60
|
+
}
|
|
45
61
|
getAngle(v) {
|
|
46
62
|
return v / this.maxSpeed * (180 + 45) - 90;
|
|
47
63
|
}
|
|
@@ -52,6 +68,15 @@ let ObcSpeedGauge = class extends SetpointMixin(LitElement) {
|
|
|
52
68
|
const barColor = this.priority === Priority.enhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
|
|
53
69
|
const setpointAngle = this.setpoint !== void 0 ? this.getAngle(this.setpoint) : void 0;
|
|
54
70
|
const maxDigits = 1;
|
|
71
|
+
const tickmarks = this.tickmarks;
|
|
72
|
+
const frame = computeRadialFrame({
|
|
73
|
+
basePadding: 48,
|
|
74
|
+
labelWidthPx: this.tickmarksInside ? 0 : estimateLabelWidthPx(tickmarks.map((t) => t.text)),
|
|
75
|
+
containerPx: measureContainerPx(this),
|
|
76
|
+
faceDiameter: this.faceDiameter
|
|
77
|
+
});
|
|
78
|
+
this._frame = frame;
|
|
79
|
+
const shownTickmarks = frame.labelsHidden ? tickmarks.map((t) => ({ ...t, text: void 0 })) : tickmarks;
|
|
55
80
|
return html`
|
|
56
81
|
<div class="container">
|
|
57
82
|
<obc-watch
|
|
@@ -62,8 +87,8 @@ let ObcSpeedGauge = class extends SetpointMixin(LitElement) {
|
|
|
62
87
|
.angleSetpointAtZeroDeadband=${this.setpointAtZeroDeadband}
|
|
63
88
|
.setpointOverride=${this.setpointOverride}
|
|
64
89
|
.animateSetpoint=${this.animateSetpoint}
|
|
65
|
-
.
|
|
66
|
-
.tickmarks=${
|
|
90
|
+
.arcFrame=${frame}
|
|
91
|
+
.tickmarks=${shownTickmarks}
|
|
67
92
|
.tickmarksInside=${this.tickmarksInside}
|
|
68
93
|
.tickmarkStyle=${this.tickmarkStyle}
|
|
69
94
|
.advices=${this._advices}
|
|
@@ -84,7 +109,7 @@ let ObcSpeedGauge = class extends SetpointMixin(LitElement) {
|
|
|
84
109
|
}
|
|
85
110
|
]}
|
|
86
111
|
></obc-watch>
|
|
87
|
-
<svg class="rudder" viewBox
|
|
112
|
+
<svg class="rudder" viewBox=${frame.viewBox}>${this.needle}</svg>
|
|
88
113
|
${this.hasReadout ? html`
|
|
89
114
|
${renderInstrumentReadout({
|
|
90
115
|
className: "speed-gauge-value",
|
|
@@ -253,6 +278,9 @@ __decorateClass([
|
|
|
253
278
|
__decorateClass([
|
|
254
279
|
property({ type: Number })
|
|
255
280
|
], ObcSpeedGauge.prototype, "fractionDigits", 2);
|
|
281
|
+
__decorateClass([
|
|
282
|
+
property({ type: Number, attribute: "face-diameter" })
|
|
283
|
+
], ObcSpeedGauge.prototype, "faceDiameter", 2);
|
|
256
284
|
ObcSpeedGauge = __decorateClass([
|
|
257
285
|
customElement("obc-speed-gauge")
|
|
258
286
|
], ObcSpeedGauge);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speed-gauge.js","sources":["../../../src/navigation-instruments/speed-gauge/speed-gauge.ts"],"sourcesContent":["import {LitElement, css, html, nothing, svg} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {Tickmark, TickmarkStyle, TickmarkType} from '../watch/tickmark.js';\nimport {WatchCircleType} from '../watch/watch.js';\nimport {AdviceType, AngleAdviceRaw, AdviceState} from '../watch/advice.js';\nimport {SetpointMixin} from '../../svghelpers/setpoint-mixin.js';\nimport {Priority} from '../types.js';\nimport {renderInstrumentReadout} from '../readout/instrument-readout.js';\nimport {ReadoutDirection} from '../readout/readout.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcSpeedGaugeNeedleType {\n full = 'full',\n bar = 'bar',\n}\n\nexport interface SpeedAdvice {\n minSpeed: number;\n maxSpeed: number;\n type: AdviceType;\n hinted: boolean;\n}\n\n/**\n * `<obc-speed-gauge>` — Radial speed gauge with needle and optional readout.\n *\n * `ObcSpeedGauge` renders a 225° arc gauge (−90° to +135°) that displays\n * the current speed with a configurable full-length or bar needle. It layers\n * an `<obc-watch>` base with a needle SVG overlay and an optional numeric\n * readout field. It inherits a full setpoint property bundle from\n * {@link SetpointMixin}, including auto at-setpoint detection, dual-marker\n * adjustment preview, and deadband tuning.\n *\n * ## Features\n *\n * - **Two needle types**: `full` (pointer with center dot) and `bar`\n * (short indicator bar) via `needleType`.\n * - **Bipolar range support**: When `minSpeed < 0`, negative tickmarks are\n * rendered with `main` tick style.\n * - **Optional readout**: Enable `hasReadout` to display an\n * `<obc-readout>` with the current speed, unit (KN), and label (STW).\n * - **Setpoint via mixin**: `setpoint`, `newSetpoint`, `touching`,\n * `autoAtSetpointDeadband`, `setpointOverride`, and all other setpoint\n * properties are provided by `SetpointMixin`; the setpoint angle and\n * at-setpoint state are computed and forwarded to `<obc-watch>`.\n * - **Speed advice zones**: Pass an array of {@link SpeedAdvice} objects to\n * render caution/alert arcs; triggered state is derived from whether the\n * current speed falls inside the advice range.\n *\n * ## Usage Guidelines\n *\n * - Set `maxSpeed` (and optionally `minSpeed`) to define the gauge range.\n * - Use `priority` to switch between regular and enhanced color palettes\n * (default: `Priority.regular`).\n * - Provide `tickmarkInterval` to control tickmark spacing.\n * - Enable `showLabels` to show numeric labels at primary tickmarks.\n * - Enable `tickmarksInside` to render tickmarks inside the ring.\n * - Enable `hasReadout` to display the numeric value below the gauge.\n *\n * ## Best Practices\n *\n * - Prefer `SetpointMixin` properties (`setpoint`, `touching`, etc.) over\n * any legacy aliases — the mixin is the single source of truth.\n * - The needle overlay SVG uses viewBox `−224 −224 448 448` to align with\n * the `<obc-watch>` layer.\n *\n * ## Example\n *\n * ```html\n * <obc-speed-gauge\n * speed=\"12.5\"\n * maxSpeed=\"25\"\n * needleType=\"full\"\n * enhanced\n * showLabels\n * hasReadout\n * tickmarkInterval=\"5\"\n * setpoint=\"15\"\n * ></obc-speed-gauge>\n * ```\n *\n * @element obc-speed-gauge\n * @typedef {import('./speed-gauge.js').SpeedAdvice} SpeedAdvice\n * @stable\n */\n@customElement('obc-speed-gauge')\nexport class ObcSpeedGauge extends SetpointMixin(LitElement) {\n @property({type: Number}) speed = 0;\n @property({type: Number}) maxSpeed = 100;\n @property({type: Number}) minSpeed = 0;\n @property({type: Boolean}) showLabels: boolean = false;\n /** Whether to render tickmarks inside the ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Interval for tickmarks in speed units.\n * When undefined or <= 0, no tickmarks are shown (only the zero mark).\n */\n @property({type: Number}) tickmarkInterval: number | undefined = 20;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: String}) needleType: ObcSpeedGaugeNeedleType =\n ObcSpeedGaugeNeedleType.full;\n @property({type: Array, attribute: false}) speedAdvices: SpeedAdvice[] = [];\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n /**\n * When `true`, shows a centered `<obc-readout>` (label `STW`, unit `KN`)\n * below the gauge with the current speed. Default `false`.\n */\n @property({type: Boolean}) hasReadout: boolean = false;\n /** Readout label. Default `STW`. */\n @property({type: String}) label = 'STW';\n /** Readout unit. Default `KN`. */\n @property({type: String}) unit = 'KN';\n /** Number of fraction digits shown in the readout. Default `1`. */\n @property({type: Number}) fractionDigits = 1;\n\n getAngle(v: number): number {\n return (v / this.maxSpeed) * (180 + 45) - 90;\n }\n\n get minAngle(): number {\n return this.getAngle(this.minSpeed) - 360;\n }\n\n maxAngle = 180 - 45;\n\n override render() {\n const barColor =\n this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)';\n const setpointAngle =\n this.setpoint !== undefined ? this.getAngle(this.setpoint) : undefined;\n\n const maxDigits = 1;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .angleSetpoint=${setpointAngle}\n .newAngleSetpoint=${this.newSetpoint !== undefined\n ? this.getAngle(this.newSetpoint)\n : undefined}\n .atAngleSetpoint=${this.computeAtSetpoint(this.speed)}\n .angleSetpointAtZeroDeadband=${this.setpointAtZeroDeadband}\n .setpointOverride=${this.setpointOverride}\n .animateSetpoint=${this.animateSetpoint}\n .padding=${48}\n .tickmarks=${this.tickmarks}\n .tickmarksInside=${this.tickmarksInside}\n .tickmarkStyle=${this.tickmarkStyle}\n .advices=${this._advices}\n .areas=${[\n {\n startAngle: this.minAngle,\n endAngle: this.maxAngle,\n roundInsideCut: true,\n roundOutsideCut: true,\n },\n ]}\n .watchCircleType=${WatchCircleType.double}\n .barAreas=${[\n {\n startAngle: this.getAngle(0),\n endAngle: this.getAngle(this.speed),\n fillColor: barColor,\n },\n ]}\n ></obc-watch>\n <svg class=\"rudder\" viewBox=\"-224 -224 448 448\">${this.needle}</svg>\n ${this.hasReadout\n ? html`\n ${renderInstrumentReadout({\n className: 'speed-gauge-value',\n direction: ReadoutDirection.horizontal,\n value: this.speed,\n label: this.label,\n unit: this.unit,\n fractionDigits: this.fractionDigits,\n maxDigits,\n priority: this.priority,\n })}\n `\n : nothing}\n </div>\n `;\n }\n\n get needle() {\n const needleColor =\n this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n if (this.needleType === ObcSpeedGaugeNeedleType.full) {\n return svg`<g transform=\"rotate(${this.getAngle(this.speed)}) translate(-256, -256)\">\n <circle cx=\"256\" cy=\"256\" r=\"14\" fill=${needleColor}/>\n <rect x=\"250\" y=\"96\" width=\"12\" height=\"192\" rx=\"6\" fill=${needleColor}/>\n <rect x=\"252\" y=\"98\" width=\"8\" height=\"188\" rx=\"4\" stroke=${needleColor} fill=${needleColor} stroke-width=\"4\"/>\n </svg> \n`;\n } else {\n return svg`<g transform=\"rotate(${this.getAngle(this.speed)}) translate(-256, -256)\">\n<rect x=\"252\" y=\"96\" width=\"8\" height=\"48\" rx=\"4\" fill=${needleColor} stroke=\"var(--border-silhouette-color)\"/>\n</svg>\n `;\n }\n }\n\n get tickmarks(): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n\n // Tickmarks — skip when undefined or <= 0 to prevent infinite loops\n const interval = this.tickmarkInterval;\n if (interval !== undefined && interval > 0 && Number.isFinite(interval)) {\n for (let i = interval; i < this.maxSpeed; i += interval) {\n tickmarks.push({\n angle: this.getAngle(i),\n type: TickmarkType.primary,\n text: this.showLabels ? i.toString() : undefined,\n });\n }\n\n if (this.showLabels && this.maxSpeed % interval === 0) {\n tickmarks.push({\n angle: this.getAngle(this.maxSpeed),\n type: TickmarkType.textOnly,\n text: this.showLabels ? this.maxSpeed.toString() : undefined,\n });\n }\n\n for (let i = -interval; i > this.minSpeed; i -= interval) {\n tickmarks.push({\n angle: this.getAngle(i),\n type: TickmarkType.main,\n text: this.showLabels ? i.toString() : undefined,\n });\n }\n\n if (this.showLabels && this.minSpeed % interval === 0) {\n tickmarks.push({\n angle: this.getAngle(this.minSpeed),\n type: TickmarkType.textOnly,\n text: this.showLabels ? this.minSpeed.toString() : undefined,\n });\n }\n }\n\n // Zero tickmark\n tickmarks.push({\n angle: this.getAngle(0),\n type: this.minSpeed < 0 ? TickmarkType.main : TickmarkType.textOnly,\n text: this.showLabels ? '0' : undefined,\n });\n\n return tickmarks;\n }\n\n get _advices(): AngleAdviceRaw[] {\n return this.speedAdvices.map((speedAdvice) => {\n const minAngle = this.getAngle(speedAdvice.minSpeed);\n const maxAngle = this.getAngle(speedAdvice.maxSpeed);\n let state = speedAdvice.hinted ? AdviceState.hinted : AdviceState.regular;\n if (\n this.speed >= speedAdvice.minSpeed &&\n this.speed <= speedAdvice.maxSpeed\n ) {\n state = AdviceState.triggered;\n }\n\n return {\n minAngle,\n maxAngle,\n type: speedAdvice.type,\n state,\n hideMinTickmark: speedAdvice.minSpeed === this.minSpeed,\n hideMaxTickmark: speedAdvice.maxSpeed === this.maxSpeed,\n };\n });\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n obc-watch {\n anchor-name: --watch;\n }\n\n .speed-gauge-value {\n position: absolute;\n top: clamp(\n 70%,\n calc(80% - (anchor-size(--watch height) - 200px) * 0.2),\n 80%\n );\n left: 50%;\n transform: translateX(-50%);\n width: fit-content;\n height: fit-content;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-speed-gauge': ObcSpeedGauge;\n }\n}\n"],"names":["ObcSpeedGaugeNeedleType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"speed-gauge.js","sources":["../../../src/navigation-instruments/speed-gauge/speed-gauge.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing, svg} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n estimateLabelWidthPx,\n measureContainerPx,\n observeInnerBox,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {Tickmark, TickmarkStyle, TickmarkType} from '../watch/tickmark.js';\nimport {WatchCircleType} from '../watch/watch.js';\nimport {AdviceType, AngleAdviceRaw, AdviceState} from '../watch/advice.js';\nimport {SetpointMixin} from '../../svghelpers/setpoint-mixin.js';\nimport {Priority} from '../types.js';\nimport {renderInstrumentReadout} from '../readout/instrument-readout.js';\nimport {ReadoutDirection} from '../readout/readout.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum ObcSpeedGaugeNeedleType {\n full = 'full',\n bar = 'bar',\n}\n\nexport interface SpeedAdvice {\n minSpeed: number;\n maxSpeed: number;\n type: AdviceType;\n hinted: boolean;\n}\n\n/**\n * `<obc-speed-gauge>` — Radial speed gauge with needle and optional readout.\n *\n * `ObcSpeedGauge` renders a 225° arc gauge (−90° to +135°) that displays\n * the current speed with a configurable full-length or bar needle. It layers\n * an `<obc-watch>` base with a needle SVG overlay and an optional numeric\n * readout field. It inherits a full setpoint property bundle from\n * {@link SetpointMixin}, including auto at-setpoint detection, dual-marker\n * adjustment preview, and deadband tuning.\n *\n * ## Features\n *\n * - **Two needle types**: `full` (pointer with center dot) and `bar`\n * (short indicator bar) via `needleType`.\n * - **Bipolar range support**: When `minSpeed < 0`, negative tickmarks are\n * rendered with `main` tick style.\n * - **Optional readout**: Enable `hasReadout` to display an\n * `<obc-readout>` with the current speed, unit (KN), and label (STW).\n * - **Setpoint via mixin**: `setpoint`, `newSetpoint`, `touching`,\n * `autoAtSetpointDeadband`, `setpointOverride`, and all other setpoint\n * properties are provided by `SetpointMixin`; the setpoint angle and\n * at-setpoint state are computed and forwarded to `<obc-watch>`.\n * - **Speed advice zones**: Pass an array of {@link SpeedAdvice} objects to\n * render caution/alert arcs; triggered state is derived from whether the\n * current speed falls inside the advice range.\n *\n * ## Usage Guidelines\n *\n * - Set `maxSpeed` (and optionally `minSpeed`) to define the gauge range.\n * - Use `priority` to switch between regular and enhanced color palettes\n * (default: `Priority.regular`).\n * - Provide `tickmarkInterval` to control tickmark spacing.\n * - Enable `showLabels` to show numeric labels at primary tickmarks.\n * - Enable `tickmarksInside` to render tickmarks inside the ring.\n * - Enable `hasReadout` to display the numeric value below the gauge.\n *\n * ## Best Practices\n *\n * - Prefer `SetpointMixin` properties (`setpoint`, `touching`, etc.) over\n * any legacy aliases — the mixin is the single source of truth.\n * - The needle overlay SVG uses viewBox `−224 −224 448 448` to align with\n * the `<obc-watch>` layer.\n *\n * ## Example\n *\n * ```html\n * <obc-speed-gauge\n * speed=\"12.5\"\n * maxSpeed=\"25\"\n * needleType=\"full\"\n * enhanced\n * showLabels\n * hasReadout\n * tickmarkInterval=\"5\"\n * setpoint=\"15\"\n * ></obc-speed-gauge>\n * ```\n *\n * @element obc-speed-gauge\n * @typedef {import('./speed-gauge.js').SpeedAdvice} SpeedAdvice\n * @stable\n */\n@customElement('obc-speed-gauge')\nexport class ObcSpeedGauge extends SetpointMixin(LitElement) {\n @property({type: Number}) speed = 0;\n @property({type: Number}) maxSpeed = 100;\n @property({type: Number}) minSpeed = 0;\n @property({type: Boolean}) showLabels: boolean = false;\n /** Whether to render tickmarks inside the ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Interval for tickmarks in speed units.\n * When undefined or <= 0, no tickmarks are shown (only the zero mark).\n */\n @property({type: Number}) tickmarkInterval: number | undefined = 20;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: String}) needleType: ObcSpeedGaugeNeedleType =\n ObcSpeedGaugeNeedleType.full;\n @property({type: Array, attribute: false}) speedAdvices: SpeedAdvice[] = [];\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n /**\n * When `true`, shows a centered `<obc-readout>` (label `STW`, unit `KN`)\n * below the gauge with the current speed. Default `false`.\n */\n @property({type: Boolean}) hasReadout: boolean = false;\n /** Readout label. Default `STW`. */\n @property({type: String}) label = 'STW';\n /** Readout unit. Default `KN`. */\n @property({type: String}) unit = 'KN';\n /** Number of fraction digits shown in the readout. Default `1`. */\n @property({type: Number}) fractionDigits = 1;\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 _frame: RadialFrame | undefined;\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n\n private _resizeController = new ResizeController(this, {});\n\n override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n observeInnerBox(this._resizeController, this.renderRoot);\n }\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 getAngle(v: number): number {\n return (v / this.maxSpeed) * (180 + 45) - 90;\n }\n\n get minAngle(): number {\n return this.getAngle(this.minSpeed) - 360;\n }\n\n maxAngle = 180 - 45;\n\n override render() {\n const barColor =\n this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)';\n const setpointAngle =\n this.setpoint !== undefined ? this.getAngle(this.setpoint) : undefined;\n\n const maxDigits = 1;\n\n const tickmarks = this.tickmarks;\n const frame = computeRadialFrame({\n basePadding: 48,\n labelWidthPx: this.tickmarksInside\n ? 0\n : estimateLabelWidthPx(tickmarks.map((t) => t.text)),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const shownTickmarks = frame.labelsHidden\n ? tickmarks.map((t) => ({...t, text: undefined}))\n : tickmarks;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .angleSetpoint=${setpointAngle}\n .newAngleSetpoint=${this.newSetpoint !== undefined\n ? this.getAngle(this.newSetpoint)\n : undefined}\n .atAngleSetpoint=${this.computeAtSetpoint(this.speed)}\n .angleSetpointAtZeroDeadband=${this.setpointAtZeroDeadband}\n .setpointOverride=${this.setpointOverride}\n .animateSetpoint=${this.animateSetpoint}\n .arcFrame=${frame}\n .tickmarks=${shownTickmarks}\n .tickmarksInside=${this.tickmarksInside}\n .tickmarkStyle=${this.tickmarkStyle}\n .advices=${this._advices}\n .areas=${[\n {\n startAngle: this.minAngle,\n endAngle: this.maxAngle,\n roundInsideCut: true,\n roundOutsideCut: true,\n },\n ]}\n .watchCircleType=${WatchCircleType.double}\n .barAreas=${[\n {\n startAngle: this.getAngle(0),\n endAngle: this.getAngle(this.speed),\n fillColor: barColor,\n },\n ]}\n ></obc-watch>\n <svg class=\"rudder\" viewBox=${frame.viewBox}>${this.needle}</svg>\n ${this.hasReadout\n ? html`\n ${renderInstrumentReadout({\n className: 'speed-gauge-value',\n direction: ReadoutDirection.horizontal,\n value: this.speed,\n label: this.label,\n unit: this.unit,\n fractionDigits: this.fractionDigits,\n maxDigits,\n priority: this.priority,\n })}\n `\n : nothing}\n </div>\n `;\n }\n\n get needle() {\n const needleColor =\n this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n if (this.needleType === ObcSpeedGaugeNeedleType.full) {\n return svg`<g transform=\"rotate(${this.getAngle(this.speed)}) translate(-256, -256)\">\n <circle cx=\"256\" cy=\"256\" r=\"14\" fill=${needleColor}/>\n <rect x=\"250\" y=\"96\" width=\"12\" height=\"192\" rx=\"6\" fill=${needleColor}/>\n <rect x=\"252\" y=\"98\" width=\"8\" height=\"188\" rx=\"4\" stroke=${needleColor} fill=${needleColor} stroke-width=\"4\"/>\n </svg> \n`;\n } else {\n return svg`<g transform=\"rotate(${this.getAngle(this.speed)}) translate(-256, -256)\">\n<rect x=\"252\" y=\"96\" width=\"8\" height=\"48\" rx=\"4\" fill=${needleColor} stroke=\"var(--border-silhouette-color)\"/>\n</svg>\n `;\n }\n }\n\n get tickmarks(): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n\n // Tickmarks — skip when undefined or <= 0 to prevent infinite loops\n const interval = this.tickmarkInterval;\n if (interval !== undefined && interval > 0 && Number.isFinite(interval)) {\n for (let i = interval; i < this.maxSpeed; i += interval) {\n tickmarks.push({\n angle: this.getAngle(i),\n type: TickmarkType.primary,\n text: this.showLabels ? i.toString() : undefined,\n });\n }\n\n if (this.showLabels && this.maxSpeed % interval === 0) {\n tickmarks.push({\n angle: this.getAngle(this.maxSpeed),\n type: TickmarkType.textOnly,\n text: this.showLabels ? this.maxSpeed.toString() : undefined,\n });\n }\n\n for (let i = -interval; i > this.minSpeed; i -= interval) {\n tickmarks.push({\n angle: this.getAngle(i),\n type: TickmarkType.main,\n text: this.showLabels ? i.toString() : undefined,\n });\n }\n\n if (this.showLabels && this.minSpeed % interval === 0) {\n tickmarks.push({\n angle: this.getAngle(this.minSpeed),\n type: TickmarkType.textOnly,\n text: this.showLabels ? this.minSpeed.toString() : undefined,\n });\n }\n }\n\n // Zero tickmark\n tickmarks.push({\n angle: this.getAngle(0),\n type: this.minSpeed < 0 ? TickmarkType.main : TickmarkType.textOnly,\n text: this.showLabels ? '0' : undefined,\n });\n\n return tickmarks;\n }\n\n get _advices(): AngleAdviceRaw[] {\n return this.speedAdvices.map((speedAdvice) => {\n const minAngle = this.getAngle(speedAdvice.minSpeed);\n const maxAngle = this.getAngle(speedAdvice.maxSpeed);\n let state = speedAdvice.hinted ? AdviceState.hinted : AdviceState.regular;\n if (\n this.speed >= speedAdvice.minSpeed &&\n this.speed <= speedAdvice.maxSpeed\n ) {\n state = AdviceState.triggered;\n }\n\n return {\n minAngle,\n maxAngle,\n type: speedAdvice.type,\n state,\n hideMinTickmark: speedAdvice.minSpeed === this.minSpeed,\n hideMaxTickmark: speedAdvice.maxSpeed === this.maxSpeed,\n };\n });\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n obc-watch {\n anchor-name: --watch;\n }\n\n .speed-gauge-value {\n position: absolute;\n top: clamp(\n 70%,\n calc(80% - (anchor-size(--watch height) - 200px) * 0.2),\n 80%\n );\n left: 50%;\n transform: translateX(-50%);\n width: fit-content;\n height: fit-content;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-speed-gauge': ObcSpeedGauge;\n }\n}\n"],"names":["ObcSpeedGaugeNeedleType"],"mappings":"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"}
|
|
@@ -119,7 +119,20 @@ export declare class ObcWatch extends LitElement {
|
|
|
119
119
|
private _setpointCssAngle;
|
|
120
120
|
/** Whether the setpoint CSS angle has been initialised (to skip transition on first render). */
|
|
121
121
|
private _setpointCssAngleInit;
|
|
122
|
+
/**
|
|
123
|
+
* Explicit padding override in SVG units: the un-zoomed viewBox becomes
|
|
124
|
+
* exactly `(176 + padding) * 2`. Setting it disables the automatic
|
|
125
|
+
* width-aware label reserve (issue #1021) — the caller owns label room.
|
|
126
|
+
*/
|
|
122
127
|
padding: number | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* Outer-ring diameter in CSS pixels. When set, the instrument renders at a
|
|
130
|
+
* fixed intrinsic size derived from the ring, arc shape and label reserve —
|
|
131
|
+
* so instruments sharing the same value have identical ring circumference
|
|
132
|
+
* regardless of label width or arc extent (like obc-donut-chart's
|
|
133
|
+
* fixedHeight). When unset (default), the instrument fills its container.
|
|
134
|
+
*/
|
|
135
|
+
faceDiameter: number | undefined;
|
|
123
136
|
areas: WatchArea[];
|
|
124
137
|
barAreas: WatchBarArea[];
|
|
125
138
|
needles: WatchNeedle[];
|
|
@@ -195,11 +208,21 @@ export declare class ObcWatch extends LitElement {
|
|
|
195
208
|
*/
|
|
196
209
|
private get _effectiveRpm();
|
|
197
210
|
private _resizeController;
|
|
211
|
+
firstUpdated(changed: PropertyValues): void;
|
|
198
212
|
willUpdate(changed: PropertyValues): void;
|
|
199
213
|
disconnectedCallback(): void;
|
|
200
214
|
updated(changed: PropertyValues): void;
|
|
201
215
|
private get innerRingRadius();
|
|
202
216
|
private _rOff;
|
|
217
|
+
/**
|
|
218
|
+
* Set by the frame when the label reserve exceeded its cap: tick label
|
|
219
|
+
* texts are dropped instead of clipped (see radial-frame.ts).
|
|
220
|
+
*/
|
|
221
|
+
private _labelsHidden;
|
|
222
|
+
/** The frame of the last render, when computed internally (no arcFrame). */
|
|
223
|
+
private _ownFrame;
|
|
224
|
+
/** Whether the host size styles were set by applyPinnedHostSize. */
|
|
225
|
+
private _hostSizePinned;
|
|
203
226
|
/**
|
|
204
227
|
* Radius for a dial-band edge under zoom: additive (`base + _rOff`), keeping
|
|
205
228
|
* band thickness constant in SVG units. INVARIANT: every band-edge radius
|
|
@@ -215,7 +238,12 @@ export declare class ObcWatch extends LitElement {
|
|
|
215
238
|
private renderBars;
|
|
216
239
|
private renderNeedles;
|
|
217
240
|
private getScale;
|
|
218
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Pixel width of the widest outside label, feeding the frame's label
|
|
243
|
+
* reserve (issue #1021). Explicit `padding` is a hard geometry override
|
|
244
|
+
* and disables the reserve, preserving legacy consumer output.
|
|
245
|
+
*/
|
|
246
|
+
private getLabelWidthPx;
|
|
219
247
|
render(): import('lit-html').TemplateResult<1>;
|
|
220
248
|
private getRotColors;
|
|
221
249
|
private renderRot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EAMf,MAAM,KAAK,CAAC;AAeb,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAa,cAAc,EAAe,MAAM,aAAa,CAAC;AACrE,OAAO,EAAC,QAAQ,EAAE,aAAa,EAAW,MAAM,eAAe,CAAC;AAChE,OAAO,EAAC,aAAa,EAAC,CAAC;AACvB,OAAO,EACL,OAAO,EACP,WAAW,EAQZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAC,OAAO,EAAE,WAAW,EAAC,CAAC;AAW9B,OAAO,EAAC,WAAW,EAAE,eAAe,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AAGvE,OAAO,
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import { VesselImageSize, vesselImages } from "./vessel.js";
|
|
|
15
15
|
import { VesselImage } from "./vessel.js";
|
|
16
16
|
import { renderWind, renderCurrent } from "./environment.js";
|
|
17
17
|
import { customElement } from "../../decorator.js";
|
|
18
|
-
import {
|
|
18
|
+
import { observeInnerBox, applyPinnedHostSize, measureContainerPx, NSWE_LABEL_WIDTH_PX, estimateLabelWidthPx, computeRadialFrame } from "../../svghelpers/radial-frame.js";
|
|
19
19
|
var __defProp = Object.defineProperty;
|
|
20
20
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
21
21
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -103,6 +103,8 @@ let ObcWatch = class extends LitElement {
|
|
|
103
103
|
this._legacyRotationsPerMinute = 0;
|
|
104
104
|
this._resizeController = new ResizeController(this, {});
|
|
105
105
|
this._rOff = 0;
|
|
106
|
+
this._labelsHidden = false;
|
|
107
|
+
this._hostSizePinned = false;
|
|
106
108
|
}
|
|
107
109
|
set rotationsPerMinute(value) {
|
|
108
110
|
this._legacyRotationsPerMinute = value;
|
|
@@ -124,6 +126,10 @@ let ObcWatch = class extends LitElement {
|
|
|
124
126
|
}
|
|
125
127
|
return this._legacyRotationsPerMinute;
|
|
126
128
|
}
|
|
129
|
+
firstUpdated(changed) {
|
|
130
|
+
super.firstUpdated(changed);
|
|
131
|
+
observeInnerBox(this._resizeController, this.renderRoot);
|
|
132
|
+
}
|
|
127
133
|
willUpdate(changed) {
|
|
128
134
|
super.willUpdate(changed);
|
|
129
135
|
if (this._rotController && (changed.has("rateOfTurnDegreesPerMinute") || changed.has("rotDotAnimationFactor") || changed.has("rotationsPerMinute"))) {
|
|
@@ -148,6 +154,11 @@ let ObcWatch = class extends LitElement {
|
|
|
148
154
|
}
|
|
149
155
|
updated(changed) {
|
|
150
156
|
super.updated(changed);
|
|
157
|
+
this._hostSizePinned = applyPinnedHostSize(
|
|
158
|
+
this,
|
|
159
|
+
this.arcFrame ? void 0 : this._ownFrame,
|
|
160
|
+
this._hostSizePinned
|
|
161
|
+
);
|
|
151
162
|
const el = this.rotType ? this.renderRoot.querySelector("#rot-spinner") : null;
|
|
152
163
|
if (!el) {
|
|
153
164
|
this._rotController = disposeRotController(this, this._rotController);
|
|
@@ -445,30 +456,26 @@ let ObcWatch = class extends LitElement {
|
|
|
445
456
|
});
|
|
446
457
|
}
|
|
447
458
|
getScale({ width, height }) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (clientWidth === 0 || clientHeight === 0) {
|
|
451
|
-
const box = this.parentElement?.getBoundingClientRect();
|
|
452
|
-
if (box) {
|
|
453
|
-
clientWidth = box.width;
|
|
454
|
-
clientHeight = box.height;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
const scale = Math.min(clientWidth / width, clientHeight / height);
|
|
459
|
+
const container = measureContainerPx(this);
|
|
460
|
+
const scale = Math.min(container.width / width, container.height / height);
|
|
458
461
|
if (!Number.isFinite(scale) || scale <= 0) {
|
|
459
462
|
return 1;
|
|
460
463
|
}
|
|
461
464
|
return scale;
|
|
462
465
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
+
/**
|
|
467
|
+
* Pixel width of the widest outside label, feeding the frame's label
|
|
468
|
+
* reserve (issue #1021). Explicit `padding` is a hard geometry override
|
|
469
|
+
* and disables the reserve, preserving legacy consumer output.
|
|
470
|
+
*/
|
|
471
|
+
getLabelWidthPx() {
|
|
472
|
+
if (this.padding !== void 0 || this.tickmarksInside) {
|
|
473
|
+
return 0;
|
|
466
474
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
return 24 * 2.5;
|
|
475
|
+
if (this.showLabels) {
|
|
476
|
+
return NSWE_LABEL_WIDTH_PX;
|
|
470
477
|
}
|
|
471
|
-
return
|
|
478
|
+
return estimateLabelWidthPx(this.tickmarks.map((t) => t.text));
|
|
472
479
|
}
|
|
473
480
|
render() {
|
|
474
481
|
let width;
|
|
@@ -476,31 +483,33 @@ let ObcWatch = class extends LitElement {
|
|
|
476
483
|
let viewBox;
|
|
477
484
|
if (this.arcFrame) {
|
|
478
485
|
this._rOff = this.arcFrame.radiusOffset;
|
|
486
|
+
this._labelsHidden = false;
|
|
487
|
+
this._ownFrame = void 0;
|
|
479
488
|
width = this.arcFrame.width;
|
|
480
489
|
height = this.arcFrame.height;
|
|
481
490
|
viewBox = this.arcFrame.viewBox;
|
|
482
|
-
} else
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
491
|
+
} else {
|
|
492
|
+
const frame = computeRadialFrame({
|
|
493
|
+
basePadding: this.padding ?? 24,
|
|
494
|
+
labelWidthPx: this.getLabelWidthPx(),
|
|
495
|
+
clips: {
|
|
496
|
+
top: this.clipTop,
|
|
497
|
+
bottom: this.clipBottom,
|
|
498
|
+
left: this.clipLeft,
|
|
499
|
+
right: this.clipRight
|
|
500
|
+
},
|
|
501
|
+
containerPx: measureContainerPx(this),
|
|
502
|
+
faceDiameter: this.faceDiameter,
|
|
503
|
+
zoomToFitArc: this.zoomToFitArc,
|
|
486
504
|
areas: this.areas,
|
|
487
|
-
|
|
488
|
-
innerRadius: this.innerRingRadius,
|
|
489
|
-
extension: ext,
|
|
490
|
-
targetSize
|
|
505
|
+
innerRadius: this.innerRingRadius
|
|
491
506
|
});
|
|
492
507
|
this._rOff = frame.radiusOffset;
|
|
508
|
+
this._labelsHidden = frame.labelsHidden;
|
|
509
|
+
this._ownFrame = frame;
|
|
493
510
|
width = frame.width;
|
|
494
511
|
height = frame.height;
|
|
495
512
|
viewBox = frame.viewBox;
|
|
496
|
-
} else {
|
|
497
|
-
this._rOff = 0;
|
|
498
|
-
const full = (176 + this.getPadding()) * 2;
|
|
499
|
-
width = full * (1 - this.clipLeft / 100 - this.clipRight / 100);
|
|
500
|
-
height = full * (1 - this.clipTop / 100 - this.clipBottom / 100);
|
|
501
|
-
const left = -full / 2 + full * this.clipLeft / 100;
|
|
502
|
-
const top = -full / 2 + full * this.clipTop / 100;
|
|
503
|
-
viewBox = `${left} ${top} ${width} ${height}`;
|
|
504
513
|
}
|
|
505
514
|
const rOff = this._rOff;
|
|
506
515
|
const scale = this.getScale({ width, height });
|
|
@@ -514,7 +523,7 @@ let ObcWatch = class extends LitElement {
|
|
|
514
523
|
size: t.type,
|
|
515
524
|
style: this.tickmarkStyle,
|
|
516
525
|
scale,
|
|
517
|
-
text: this.showLabels ? void 0 : t.text,
|
|
526
|
+
text: this.showLabels || this._labelsHidden ? void 0 : t.text,
|
|
518
527
|
inside: this.tickmarksInside,
|
|
519
528
|
textRadius,
|
|
520
529
|
rotation: this.rotation,
|
|
@@ -525,9 +534,11 @@ let ObcWatch = class extends LitElement {
|
|
|
525
534
|
})
|
|
526
535
|
);
|
|
527
536
|
const advices = this.advices ? this.advices.map((a) => renderAdvice(a, rOff)) : nothing;
|
|
528
|
-
const
|
|
537
|
+
const showNsweLabels = this.showLabels && !this._labelsHidden;
|
|
538
|
+
const showNorthArrow = this.northArrow && !this._labelsHidden;
|
|
539
|
+
const insideLabels = this.tickmarksInside && showNsweLabels;
|
|
529
540
|
const includeNorth = !this.northArrow;
|
|
530
|
-
const labelPositions =
|
|
541
|
+
const labelPositions = showNsweLabels ? getLabelPositions({
|
|
531
542
|
scale,
|
|
532
543
|
inside: this.tickmarksInside,
|
|
533
544
|
innerRadius: this.innerRingRadius + rOff,
|
|
@@ -540,7 +551,7 @@ let ObcWatch = class extends LitElement {
|
|
|
540
551
|
innerRadius: this.innerRingRadius + rOff,
|
|
541
552
|
includeNorth
|
|
542
553
|
}) : nothing;
|
|
543
|
-
const northArrowEl =
|
|
554
|
+
const northArrowEl = showNorthArrow ? renderNorthArrow({
|
|
544
555
|
scale,
|
|
545
556
|
rotation: this.rotation,
|
|
546
557
|
inside: this.northArrowInside ?? this.tickmarksInside
|
|
@@ -823,6 +834,9 @@ __decorateClass([
|
|
|
823
834
|
__decorateClass([
|
|
824
835
|
property({ type: Number })
|
|
825
836
|
], ObcWatch.prototype, "padding", 2);
|
|
837
|
+
__decorateClass([
|
|
838
|
+
property({ type: Number, attribute: "face-diameter" })
|
|
839
|
+
], ObcWatch.prototype, "faceDiameter", 2);
|
|
826
840
|
__decorateClass([
|
|
827
841
|
property({ type: Array, attribute: false })
|
|
828
842
|
], ObcWatch.prototype, "areas", 2);
|